taro-bluetooth-print 2.15.2 → 2.15.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.
@@ -41,6 +41,12 @@ export declare class BluetoothPrinter extends EventEmitter<PrinterEvents> {
41
41
  * Resolve the first constructor argument to an IConnectionManager. An adapter
42
42
  * (anything implementing `connect`/`disconnect`/`write`) gets auto-wrapped for
43
43
  * backward compatibility; missing/undefined falls back to a default manager.
44
+ *
45
+ * Disambiguation: `IConnectionManager` exposes `getState()` (manager-only
46
+ * method on the interface). Adapters only have `connect`/`disconnect`/`write`.
47
+ * Using `getState` as the discriminator correctly identifies a pre-built
48
+ * manager vs. a raw adapter — using `connect` (which both have) silently
49
+ * re-wrapped managers and broke isConnected() (v2.15.3 fix).
44
50
  */
45
51
  private resolveConnectionManager;
46
52
  /**
@@ -76,6 +82,37 @@ export declare class BluetoothPrinter extends EventEmitter<PrinterEvents> {
76
82
  showText?: boolean;
77
83
  }): this;
78
84
  setOptions(options: IAdapterOptions): this;
85
+ /**
86
+ * Write a pre-built byte buffer directly to the connected printer,
87
+ * bypassing the CommandBuilder entirely. Use this when a driver (such as
88
+ * TsplDriver, ZplDriver, StarPrinter, CPCL or any custom protocol) emits
89
+ * its own byte stream and you want the same connection / chunking /
90
+ * progress / pause pipeline as the standard print() path.
91
+ *
92
+ * Unlike print() — which calls commandBuilder.getBuffer() then clears it —
93
+ * writeRaw() does NOT touch the command queue. It is safe to call between
94
+ * text() / qr() / cut() calls; those calls continue to accumulate in the
95
+ * command buffer for the next print() invocation.
96
+ *
97
+ * @param buffer Bytes to send (e.g. `tsplDriver.getBuffer()`)
98
+ * @param options Optional adapter overrides (chunkSize, delay, retries).
99
+ * Forwarded to PrintJobManager.setOptions() before start.
100
+ * @throws BluetoothPrintError(CONNECTION_FAILED) if not connected
101
+ * @throws BluetoothPrintError(PRINT_JOB_FAILED) on adapter write failure
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * // TSPL label printing — full end-to-end flow now works.
106
+ * const tspl = new TsplDriver()
107
+ * .size(60, 40)
108
+ * .gap(3)
109
+ * .clear()
110
+ * .text('Hello', { x: 20, y: 20, font: 3 })
111
+ * .print(1, 1);
112
+ * await printer.writeRaw(tspl.getBuffer());
113
+ * ```
114
+ */
115
+ writeRaw(buffer: Uint8Array, options?: IAdapterOptions): Promise<void>;
79
116
  /**
80
117
  * Pauses the current print job.
81
118
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taro-bluetooth-print",
3
- "version": "2.15.2",
3
+ "version": "2.15.3",
4
4
  "description": "Taro 蓝牙打印库 v2.6 - 轻量级、高性能、跨平台支持微信、支付宝、百度、字节跳动小程序及H5 Web Bluetooth",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs.js",
@@ -10,8 +10,7 @@
10
10
  ".": {
11
11
  "types": "./dist/types/index.d.ts",
12
12
  "import": "./dist/index.es.js",
13
- "require": "./dist/index.cjs.js",
14
- "default": "./dist/index.umd.js"
13
+ "require": "./dist/index.cjs.js"
15
14
  },
16
15
  "./core": {
17
16
  "types": "./dist/types/core/index.d.ts",
@@ -25,6 +24,10 @@
25
24
  "types": "./dist/types/adapters/index.d.ts",
26
25
  "import": "./dist/adapters/index.es.js"
27
26
  },
27
+ "./encoding": {
28
+ "types": "./dist/types/encoding/index.d.ts",
29
+ "import": "./dist/encoding/index.es.js"
30
+ },
28
31
  "./package.json": "./package.json"
29
32
  },
30
33
  "files": [
@@ -36,6 +39,7 @@
36
39
  "scripts": {
37
40
  "clean": "rimraf dist docs/.vitepress/dist",
38
41
  "build": "vite build",
42
+ "build:umd": "vite build --config vite.umd.config.ts",
39
43
  "dev": "vite build --watch",
40
44
  "docs:dev": "vitepress dev docs",
41
45
  "docs:build": "vitepress build docs",
@@ -71,6 +71,12 @@ export class BluetoothPrinter extends EventEmitter<PrinterEvents> {
71
71
  * Resolve the first constructor argument to an IConnectionManager. An adapter
72
72
  * (anything implementing `connect`/`disconnect`/`write`) gets auto-wrapped for
73
73
  * backward compatibility; missing/undefined falls back to a default manager.
74
+ *
75
+ * Disambiguation: `IConnectionManager` exposes `getState()` (manager-only
76
+ * method on the interface). Adapters only have `connect`/`disconnect`/`write`.
77
+ * Using `getState` as the discriminator correctly identifies a pre-built
78
+ * manager vs. a raw adapter — using `connect` (which both have) silently
79
+ * re-wrapped managers and broke isConnected() (v2.15.3 fix).
74
80
  */
75
81
  private resolveConnectionManager(
76
82
  arg: IConnectionManager | IPrinterAdapter | undefined
@@ -78,11 +84,11 @@ export class BluetoothPrinter extends EventEmitter<PrinterEvents> {
78
84
  if (!arg) {
79
85
  return new ConnectionManager();
80
86
  }
81
- // Adapters expose `connect`; managers expose `getState`. Disambiguate by method presence.
82
- if (typeof (arg as IPrinterAdapter).connect === 'function') {
83
- return new ConnectionManager(arg as IPrinterAdapter);
87
+ // Managers expose `getState`; adapters do not. Disambiguate by method presence.
88
+ if (typeof (arg as IConnectionManager).getState === 'function') {
89
+ return arg as IConnectionManager;
84
90
  }
85
- return arg as IConnectionManager;
91
+ return new ConnectionManager(arg as IPrinterAdapter);
86
92
  }
87
93
 
88
94
  /**
@@ -224,6 +230,62 @@ export class BluetoothPrinter extends EventEmitter<PrinterEvents> {
224
230
  return this;
225
231
  }
226
232
 
233
+ /**
234
+ * Write a pre-built byte buffer directly to the connected printer,
235
+ * bypassing the CommandBuilder entirely. Use this when a driver (such as
236
+ * TsplDriver, ZplDriver, StarPrinter, CPCL or any custom protocol) emits
237
+ * its own byte stream and you want the same connection / chunking /
238
+ * progress / pause pipeline as the standard print() path.
239
+ *
240
+ * Unlike print() — which calls commandBuilder.getBuffer() then clears it —
241
+ * writeRaw() does NOT touch the command queue. It is safe to call between
242
+ * text() / qr() / cut() calls; those calls continue to accumulate in the
243
+ * command buffer for the next print() invocation.
244
+ *
245
+ * @param buffer Bytes to send (e.g. `tsplDriver.getBuffer()`)
246
+ * @param options Optional adapter overrides (chunkSize, delay, retries).
247
+ * Forwarded to PrintJobManager.setOptions() before start.
248
+ * @throws BluetoothPrintError(CONNECTION_FAILED) if not connected
249
+ * @throws BluetoothPrintError(PRINT_JOB_FAILED) on adapter write failure
250
+ *
251
+ * @example
252
+ * ```ts
253
+ * // TSPL label printing — full end-to-end flow now works.
254
+ * const tspl = new TsplDriver()
255
+ * .size(60, 40)
256
+ * .gap(3)
257
+ * .clear()
258
+ * .text('Hello', { x: 20, y: 20, font: 3 })
259
+ * .print(1, 1);
260
+ * await printer.writeRaw(tspl.getBuffer());
261
+ * ```
262
+ */
263
+ async writeRaw(buffer: Uint8Array, options?: IAdapterOptions): Promise<void> {
264
+ if (!this.connectionManager.isConnected()) {
265
+ throw new BluetoothPrintError(
266
+ ErrorCode.CONNECTION_FAILED,
267
+ 'Printer not connected. Call connect() first.'
268
+ );
269
+ }
270
+
271
+ this.printerLogger.info(`writeRaw: ${buffer.length} bytes`);
272
+ if (options) this.printJobManager.setOptions(options);
273
+
274
+ this.updateState();
275
+ this.printJobManager.setProgressCallback((sent, total) => {
276
+ this.emit('progress', { sent, total });
277
+ });
278
+
279
+ try {
280
+ await this.printJobManager.start(buffer);
281
+ if (!this.printJobManager.isPaused()) this.emit('print-complete');
282
+ } catch (error) {
283
+ throw this.handleError(error, ErrorCode.PRINT_JOB_FAILED, 'writeRaw failed');
284
+ } finally {
285
+ this.updateState();
286
+ }
287
+ }
288
+
227
289
  /**
228
290
  * Pauses the current print job.
229
291
  */
@@ -1,44 +0,0 @@
1
- <svg width="400" height="300" viewBox="0 0 400 300" fill="none" xmlns="http://www.w3.org/2000/svg">
2
- <!-- 背景圆 -->
3
- <circle cx="200" cy="150" r="120" fill="#ecfeff" opacity="0.5"/>
4
- <circle cx="200" cy="150" r="80" fill="#cffafe" opacity="0.5"/>
5
-
6
- <!-- 手机轮廓 -->
7
- <rect x="140" y="60" width="120" height="180" rx="16" fill="#fff" stroke="#0891b2" stroke-width="3"/>
8
- <rect x="150" y="80" width="100" height="140" rx="4" fill="#f0fdfa"/>
9
-
10
- <!-- 屏幕上的打印图标 -->
11
- <rect x="165" y="95" width="70" height="50" rx="4" fill="#0891b2" opacity="0.1"/>
12
- <text x="200" y="125" font-family="Arial" font-size="24" fill="#0891b2" text-anchor="middle">🖨️</text>
13
-
14
- <!-- 小票 -->
15
- <rect x="170" y="155" width="60" height="45" rx="2" fill="#fff" stroke="#06b6d4" stroke-width="2"/>
16
- <line x1="178" y1="165" x2="222" y2="165" stroke="#94a3b8" stroke-width="2"/>
17
- <line x1="178" y1="175" x2="215" y2="175" stroke="#94a3b8" stroke-width="2"/>
18
- <line x1="178" y1="185" x2="220" y2="185" stroke="#94a3b8" stroke-width="2"/>
19
-
20
- <!-- 蓝牙符号 -->
21
- <path d="M220 120 L235 105 L235 135 L220 150 L235 165 L235 195 L220 180" stroke="#0891b2" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
22
-
23
- <!-- 打印机轮廓 -->
24
- <rect x="260" y="170" width="80" height="60" rx="6" fill="#fff" stroke="#06b6d4" stroke-width="3"/>
25
- <rect x="270" y="180" width="60" height="20" rx="2" fill="#cffafe"/>
26
- <rect x="275" y="205" width="50" height="15" rx="2" fill="#0891b2" opacity="0.2"/>
27
-
28
- <!-- 出纸 -->
29
- <rect x="275" y="235" width="50" height="25" rx="2" fill="#fff" stroke="#06b6d4" stroke-width="2"/>
30
- <line x1="283" y1="243" x2="317" y2="243" stroke="#94a3b8" stroke-width="1.5"/>
31
- <line x1="283" y1="250" x2="310" y2="250" stroke="#94a3b8" stroke-width="1.5"/>
32
-
33
- <!-- 连接线 -->
34
- <path d="M250 200 Q280 200 280 200" stroke="#0891b2" stroke-width="2" stroke-dasharray="4 4" fill="none"/>
35
-
36
- <!-- 装饰 - 代码符号 -->
37
- <text x="80" y="100" font-family="monospace" font-size="14" fill="#0891b2" opacity="0.6">&lt;/&gt;</text>
38
- <text x="320" y="90" font-family="monospace" font-size="14" fill="#06b6d4" opacity="0.6">{ }</text>
39
- <text x="100" y="220" font-family="monospace" font-size="12" fill="#0891b2" opacity="0.4">print()</text>
40
-
41
- <!-- 底部装饰 -->
42
- <circle cx="60" cy="260" r="20" fill="#cffafe" opacity="0.4"/>
43
- <circle cx="340" cy="270" r="25" fill="#ecfeff" opacity="0.4"/>
44
- </svg>