taro-bluetooth-print 2.15.3 → 2.15.4
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 -0
- package/README.md +4 -4
- package/dist/adapters/index.cjs.js +1 -1
- package/dist/adapters/index.es.js +1 -1
- package/dist/chunks/{AdapterFactory-sRvkpRnt.js → AdapterFactory-CkjGKGZN.js} +1 -1
- package/dist/chunks/{AdapterFactory-B91w5soC.js → AdapterFactory-DA4PnIrY.js} +1 -1
- package/dist/chunks/{EscPosDriver-Byd1u4Jk.js → EscPosDriver-BEwkA9KT.js} +1 -1
- package/dist/chunks/{EscPosDriver-DGK4usVf.js → EscPosDriver-ju4j3bXJ.js} +1 -1
- package/dist/chunks/gbk-data-BhfiCGRq.js +1 -0
- package/dist/chunks/gbk-data-Cunq2WDW.js +1 -0
- package/dist/chunks/{index-CNH0TeFh.js → index-Cee15KIh.js} +1 -1
- package/dist/chunks/{index-DI6d-y8j.js → index-DIquif_6.js} +1 -1
- package/dist/chunks/shared-C7eA759x.js +1 -0
- package/dist/chunks/shared-CvHoYVGG.js +1 -0
- package/dist/core/index.cjs.js +1 -1
- package/dist/core/index.es.js +1 -1
- package/dist/drivers/index.cjs.js +1 -1
- package/dist/drivers/index.es.js +1 -1
- package/dist/encoding/index.cjs.js +1 -1
- package/dist/encoding/index.es.js +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +1 -1
- package/dist/types/config/PrinterConfigManager.d.ts +58 -7
- package/dist/types/core/BluetoothPrinter.d.ts +17 -0
- package/dist/types/encoding/GbkTable.d.ts +14 -5
- package/dist/types/index.d.ts +3 -3
- package/dist/types/plugins/builtin/RetryPlugin.d.ts +19 -1
- package/dist/types/plugins/index.d.ts +1 -0
- package/dist/types/services/BatchPrintManager.d.ts +48 -2
- package/package.json +1 -1
- package/src/config/PrinterConfigManager.ts +150 -45
- package/src/core/BluetoothPrinter.ts +51 -3
- package/src/encoding/GbkTable.ts +18 -7
- package/src/index.ts +15 -3
- package/src/plugins/builtin/RetryPlugin.ts +46 -12
- package/src/plugins/index.ts +1 -0
- package/src/services/BatchPrintManager.ts +126 -8
- package/dist/chunks/shared-C3EQK7YH.js +0 -1
- package/dist/chunks/shared-DuaS72fL.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.15.4] - 2026-07-13
|
|
4
|
+
|
|
5
|
+
### Added (Phase A — 可观测性 + 重试编排)
|
|
6
|
+
|
|
7
|
+
- **`BluetoothPrinter.job-completed` / `job-failed` 事件** — 每次底层 `adapter.write()` 完成后触发,携带 `source` / `bytes` / `durationMs` / `completedAt`(失败额外带 `error: BluetoothPrintError`)。与 `print-complete`(业务级)并存:`print-complete` 用于业务提示,新事件用于精细化埋点 / SLA 监控 / 重试编排。
|
|
8
|
+
- 新类型 `JobResult` 已从 `taro-bluetooth-print` 命名导出
|
|
9
|
+
|
|
10
|
+
- **`RetryPlugin.onRetry` 回调** — 每次重试 **sleep 之前** 触发,携带 `attempt` / `maxRetries` / `delayMs` / `error`。用于 UI Toast("正在重连 2/3...")或遥测。回调内异常被捕获并 log,不会影响 retry 计时。
|
|
11
|
+
|
|
12
|
+
- **`BatchPrintManager` 失败任务管理**
|
|
13
|
+
- 新方法:`retryJob(id)` / `retryAllFailedJobs()` / `getFailedJobs()` / `clearFailedJobs()`
|
|
14
|
+
- 新事件:`batch-progress`(`{ sent, total, jobIds }`)/ `batch-failed`(`{ jobIds, bytes, error }`)/ `job-retried`(`BatchJob`)
|
|
15
|
+
- 失败任务保留在内部 `failedJobs` 缓冲中(**不**自动从队列删除),等待显式重试
|
|
16
|
+
|
|
17
|
+
- **`PrinterConfigManager.export()` / `import()` 升级为 versioned snapshot(format=1)**
|
|
18
|
+
- 字段校验(缺字段 / 类型错 → 抛 `BluetoothPrintError(INVALID_CONFIGURATION)`)
|
|
19
|
+
- `import()` 返回 `PrinterConfigImportResult`(含 `imported` / `skipped` / `format`)
|
|
20
|
+
- 向后兼容:v0 格式仍可读,但会自动升级为 v1
|
|
21
|
+
|
|
22
|
+
### Changed (Phase B — 包体积优化)
|
|
23
|
+
|
|
24
|
+
- **`GbkData` 拆分为独立 chunk** — `shared` chunk 从 **480KB → 24.7KB**(gzip 190KB → 8.78KB,**-95%**)
|
|
25
|
+
- 用户业务只需要 ES/POS 主路径时,浏览器首屏不会下载 455KB GBK 全表
|
|
26
|
+
- `gbk-data-{hash}.js` 仍按需加载(首次遇到 CJK 字符时触发)
|
|
27
|
+
|
|
28
|
+
### Testing (Phase C — 覆盖率提升)
|
|
29
|
+
|
|
30
|
+
- **77 个新单元测试**(1,359 → 1,436),覆盖率 **67.3% → 71.5%**(lines)
|
|
31
|
+
- 重点提升:
|
|
32
|
+
- `LoggingPlugin.ts` 17.85% → **100%**
|
|
33
|
+
- `EventEmitter.ts` 42.55% → **91.48%**
|
|
34
|
+
- `GbkTable.ts` 50% → **92%**
|
|
35
|
+
- `DeviceManager.ts` 59.84% → **90.9%**
|
|
36
|
+
|
|
37
|
+
### Docs (Phase D)
|
|
38
|
+
|
|
39
|
+
- `docs/api/bluetooth-printer.md` — 新增「任务级事件」章节 + `JobResult` 类型定义
|
|
40
|
+
- `docs/api/plugins.md` — RetryPlugin 字段更新为真实签名 + 新增 `onRetry` 章节 + `RetryAttempt` 类型
|
|
41
|
+
- `docs/api/batch-print-manager.md` — 事件列表重写(对齐真实 `BatchEvents`)+ 新增「失败任务管理」章节
|
|
42
|
+
|
|
3
43
|
## [2.15.3] - 2026-07-10
|
|
4
44
|
|
|
5
45
|
### Added
|
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
|
|
49
49
|
- ✅ 整个库 **0 个生产依赖**(仅 peerDep `@tarojs/taro ^3.6.22`)
|
|
50
50
|
- ✅ 严格类型契约 (`IPrinterDriver` / `IPrinterAdapter`),IDE 自动补全
|
|
51
|
-
- ✅ **1,
|
|
51
|
+
- ✅ **1,436 个测试**全绿 · **jscpd 0 重复** · **零 dead code**
|
|
52
52
|
|
|
53
53
|
---
|
|
54
54
|
|
|
@@ -235,8 +235,8 @@ printer.use(createRetryPlugin({ maxRetries: 3, backoffMultiplier: 2 }));
|
|
|
235
235
|
|
|
236
236
|
| 维度 | 数值 |
|
|
237
237
|
|:---|:---|
|
|
238
|
-
| 包体积(
|
|
239
|
-
| 测试用例 | **1,
|
|
238
|
+
| 包体积(main bundle) | **89 KB / 25.5 KB gzip**(v2.15.4+,GBK 表按需懒加载) |
|
|
239
|
+
| 测试用例 | **1,436** 个,全绿 |
|
|
240
240
|
| 代码重复 | **jscpd 0 clones** |
|
|
241
241
|
| 死代码 | **0 行** |
|
|
242
242
|
| TypeScript any 暴露 | **0 处** |
|
|
@@ -353,7 +353,7 @@ await printPromise;
|
|
|
353
353
|
git clone https://github.com/Agions/taro-bluetooth-print.git
|
|
354
354
|
cd taro-bluetooth-print
|
|
355
355
|
pnpm install
|
|
356
|
-
pnpm test #
|
|
356
|
+
pnpm test # 1436 测试
|
|
357
357
|
pnpm lint # ESLint
|
|
358
358
|
pnpm type-check # tsc --noEmit
|
|
359
359
|
pnpm build # 产物输出到 dist/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=Object.defineProperty,t=Object.defineProperties,r=Object.getOwnPropertyDescriptors,i=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,s=(t,r,i)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[r]=i,n=(e,t,r)=>new Promise((i,a)=>{var c=e=>{try{n(r.next(e))}catch(t){a(t)}},s=e=>{try{n(r.throw(e))}catch(t){a(t)}},n=e=>e.done?i(e.value):Promise.resolve(e.value).then(c,s);n((r=r.apply(e,t)).next())});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("../chunks/AdapterFactory-
|
|
1
|
+
"use strict";var e=Object.defineProperty,t=Object.defineProperties,r=Object.getOwnPropertyDescriptors,i=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,s=(t,r,i)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[r]=i,n=(e,t,r)=>new Promise((i,a)=>{var c=e=>{try{n(r.next(e))}catch(t){a(t)}},s=e=>{try{n(r.throw(e))}catch(t){a(t)}},n=e=>e.done?i(e.value):Promise.resolve(e.value).then(c,s);n((r=r.apply(e,t)).next())});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("../chunks/AdapterFactory-DA4PnIrY.js"),d=require("../chunks/shared-CvHoYVGG.js"),l=globalThis.Platform;class u extends o.C{constructor(){var e;super("ReactNativeAdapter",(e=((e,t)=>{for(var r in t||(t={}))a.call(t,r)&&s(e,r,t[r]);if(i)for(var r of i(t))c.call(t,r)&&s(e,r,t[r]);return e})({},o.D),t(e,r({maxChunkSize:512,connectionCheckInterval:0}))))}computeTimeoutMs(e){return Math.max(2e3,Math.min(1e4,1e3+10*e))}writeSingleChunk(e,t,r){return n(this,null,function*(){if(!r)return{success:!1,error:Error("RNWriteOptions required")};const i=r.arrayBufferToBase64(e.buffer);try{return yield r.bleManager.writeCharacteristicWithResponseForDevice(t.deviceId,t.serviceId,t.characteristicId,i),{success:!0}}catch(a){try{return yield r.bleManager.writeCharacteristicWithoutResponseForDevice(t.deviceId,t.serviceId,t.characteristicId,i),{success:!0}}catch(c){return{success:!1,error:d.o(c)}}}})}}class h extends o.B{constructor(e){if(super(),this.deviceCache=new Map,this.writeStrategy=new u,!(null==e?void 0:e.bleManager))throw new d.B(d.n.INVALID_CONFIGURATION,"ReactNativeAdapter requires a bleManager instance (e.g., react-native-ble-plx). Please pass { bleManager: yourBleManager } in the constructor.");this.bleManager=e.bleManager,l&&"ios"!==l.OS&&"android"!==l.OS&&d.L.scope("ReactNativeAdapter").warn(`Running on unsupported platform: ${l.OS}. BLE may not work correctly.`)}connect(e){return n(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return d.L.scope("ReactNativeAdapter").warn("Device already connected:",e),void this.updateState(d.P.CONNECTED);this.updateState(d.P.CONNECTING),d.L.scope("ReactNativeAdapter").debug("Connecting to device:",e);try{const t=15e3,r=yield d.w(this.performConnect(e),t,"Connection timeout");this.deviceCache.set(e,r),yield this.discoverServices(e,r),this.updateState(d.P.CONNECTED),d.L.scope("ReactNativeAdapter").info("Device connected successfully")}catch(t){throw this.updateState(d.P.DISCONNECTED),this.cleanupDevice(e),this.classifyConnectionError(t,e)}})}performConnect(e){return n(this,null,function*(){const t=yield this.bleManager.connectToDevice(e,{timeout:1e4});try{yield t.requestConnectionPriority()}catch(r){}return t})}disconnect(e){return n(this,null,function*(){this.validateDeviceId(e),this.updateState(d.P.DISCONNECTING),d.L.scope("ReactNativeAdapter").debug("Disconnecting from device:",e);const t=()=>{this.cleanupDevice(e),this.deviceCache.delete(e),this.updateState(d.P.DISCONNECTED),d.L.scope("ReactNativeAdapter").info("Device disconnected successfully")};try{yield this.bleManager.disconnectFromDevice(e,!0),t()}catch(r){d.L.scope("ReactNativeAdapter").warn("Disconnect error (ignored):",r),t()}})}write(e,t,r){return n(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const i=this.getServiceInfo(e),a=this.deviceCache.get(e);if(!a||!a.isConnected)throw this.cleanupDevice(e),new d.B(d.n.DEVICE_DISCONNECTED,`Device ${e} is not connected`);yield this.writeStrategy.execute(t,{deviceId:e,serviceId:i.serviceId,characteristicId:i.characteristicId},null!=r?r:{},{bleManager:this.bleManager,arrayBufferToBase64:this.arrayBufferToBase64.bind(this)})})}startDiscovery(){return new Promise((e,t)=>{try{this.bleManager.startDeviceScan(null,{allowDuplicates:!1},e=>{e&&t(d.o(e))}),e()}catch(r){t(d.o(r))}})}stopDiscovery(){return new Promise(e=>{this.bleManager.stopDeviceScan(),e()})}discoverServices(e,t){return n(this,null,function*(){yield this.discoverAndCacheServices(e,()=>n(this,null,function*(){return((yield this.bleManager.discoverAllServicesAndCharacteristicsForDevice(e)).services||[]).map(e=>({serviceId:e.uuid,characteristics:e.characteristics.map(e=>({characteristicId:e.uuid,isWritable:e.isWritableWithResponse||e.isWritableWithoutResponse}))}))}))})}arrayBufferToBase64(e){var t;const r=new Uint8Array(e);let i="";for(let a=0;a<r.byteLength;a++)i+=String.fromCharCode(null!=(t=r[a])?t:0);return globalThis.btoa(i)}}exports.AdapterFactory=o.A,exports.AlipayAdapter=o.a,exports.BaiduAdapter=o.b,exports.BaseAdapter=o.B,exports.ByteDanceAdapter=o.c,exports.MiniProgramAdapter=o.M,exports.QQAdapter=o.Q,exports.TaroAdapter=o.T,exports.WebBluetoothAdapter=o.W,exports.ReactNativeAdapter=h;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=Object.defineProperties,r=Object.getOwnPropertyDescriptors,i=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,s=(t,r,i)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[r]=i,n=(e,t,r)=>new Promise((i,a)=>{var c=e=>{try{n(r.next(e))}catch(t){a(t)}},s=e=>{try{n(r.throw(e))}catch(t){a(t)}},n=e=>e.done?i(e.value):Promise.resolve(e.value).then(c,s);n((r=r.apply(e,t)).next())});import{B as o,C as d,D as l}from"../chunks/AdapterFactory-
|
|
1
|
+
var e=Object.defineProperty,t=Object.defineProperties,r=Object.getOwnPropertyDescriptors,i=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,s=(t,r,i)=>r in t?e(t,r,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[r]=i,n=(e,t,r)=>new Promise((i,a)=>{var c=e=>{try{n(r.next(e))}catch(t){a(t)}},s=e=>{try{n(r.throw(e))}catch(t){a(t)}},n=e=>e.done?i(e.value):Promise.resolve(e.value).then(c,s);n((r=r.apply(e,t)).next())});import{B as o,C as d,D as l}from"../chunks/AdapterFactory-CkjGKGZN.js";import{A as u,a as h,b as p,c as v,M as y,Q as f,T as b,W as C}from"../chunks/AdapterFactory-CkjGKGZN.js";import{B as D,n as g,L as m,P as I,w as N,o as w}from"../chunks/shared-C7eA759x.js";const A=globalThis.Platform;class S extends d{constructor(){var e;super("ReactNativeAdapter",(e=((e,t)=>{for(var r in t||(t={}))a.call(t,r)&&s(e,r,t[r]);if(i)for(var r of i(t))c.call(t,r)&&s(e,r,t[r]);return e})({},l),t(e,r({maxChunkSize:512,connectionCheckInterval:0}))))}computeTimeoutMs(e){return Math.max(2e3,Math.min(1e4,1e3+10*e))}writeSingleChunk(e,t,r){return n(this,null,function*(){if(!r)return{success:!1,error:Error("RNWriteOptions required")};const i=r.arrayBufferToBase64(e.buffer);try{return yield r.bleManager.writeCharacteristicWithResponseForDevice(t.deviceId,t.serviceId,t.characteristicId,i),{success:!0}}catch(a){try{return yield r.bleManager.writeCharacteristicWithoutResponseForDevice(t.deviceId,t.serviceId,t.characteristicId,i),{success:!0}}catch(c){return{success:!1,error:w(c)}}}})}}class O extends o{constructor(e){if(super(),this.deviceCache=/* @__PURE__ */new Map,this.writeStrategy=new S,!(null==e?void 0:e.bleManager))throw new D(g.INVALID_CONFIGURATION,"ReactNativeAdapter requires a bleManager instance (e.g., react-native-ble-plx). Please pass { bleManager: yourBleManager } in the constructor.");this.bleManager=e.bleManager,A&&"ios"!==A.OS&&"android"!==A.OS&&m.scope("ReactNativeAdapter").warn(`Running on unsupported platform: ${A.OS}. BLE may not work correctly.`)}connect(e){return n(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return m.scope("ReactNativeAdapter").warn("Device already connected:",e),void this.updateState(I.CONNECTED);this.updateState(I.CONNECTING),m.scope("ReactNativeAdapter").debug("Connecting to device:",e);try{const t=15e3,r=yield N(this.performConnect(e),t,"Connection timeout");this.deviceCache.set(e,r),yield this.discoverServices(e,r),this.updateState(I.CONNECTED),m.scope("ReactNativeAdapter").info("Device connected successfully")}catch(t){throw this.updateState(I.DISCONNECTED),this.cleanupDevice(e),this.classifyConnectionError(t,e)}})}performConnect(e){return n(this,null,function*(){const t=yield this.bleManager.connectToDevice(e,{timeout:1e4});try{yield t.requestConnectionPriority()}catch(r){}return t})}disconnect(e){return n(this,null,function*(){this.validateDeviceId(e),this.updateState(I.DISCONNECTING),m.scope("ReactNativeAdapter").debug("Disconnecting from device:",e);const t=()=>{this.cleanupDevice(e),this.deviceCache.delete(e),this.updateState(I.DISCONNECTED),m.scope("ReactNativeAdapter").info("Device disconnected successfully")};try{yield this.bleManager.disconnectFromDevice(e,!0),t()}catch(r){m.scope("ReactNativeAdapter").warn("Disconnect error (ignored):",r),t()}})}write(e,t,r){return n(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const i=this.getServiceInfo(e),a=this.deviceCache.get(e);if(!a||!a.isConnected)throw this.cleanupDevice(e),new D(g.DEVICE_DISCONNECTED,`Device ${e} is not connected`);yield this.writeStrategy.execute(t,{deviceId:e,serviceId:i.serviceId,characteristicId:i.characteristicId},null!=r?r:{},{bleManager:this.bleManager,arrayBufferToBase64:this.arrayBufferToBase64.bind(this)})})}startDiscovery(){return new Promise((e,t)=>{try{this.bleManager.startDeviceScan(null,{allowDuplicates:!1},e=>{e&&t(w(e))}),e()}catch(r){t(w(r))}})}stopDiscovery(){return new Promise(e=>{this.bleManager.stopDeviceScan(),e()})}discoverServices(e,t){return n(this,null,function*(){yield this.discoverAndCacheServices(e,()=>n(this,null,function*(){return((yield this.bleManager.discoverAllServicesAndCharacteristicsForDevice(e)).services||[]).map(e=>({serviceId:e.uuid,characteristics:e.characteristics.map(e=>({characteristicId:e.uuid,isWritable:e.isWritableWithResponse||e.isWritableWithoutResponse}))}))}))})}arrayBufferToBase64(e){var t;const r=new Uint8Array(e);let i="";for(let a=0;a<r.byteLength;a++)i+=String.fromCharCode(null!=(t=r[a])?t:0);return globalThis.btoa(i)}}export{u as AdapterFactory,h as AlipayAdapter,p as BaiduAdapter,o as BaseAdapter,v as ByteDanceAdapter,y as MiniProgramAdapter,f as QQAdapter,O as ReactNativeAdapter,b as TaroAdapter,C as WebBluetoothAdapter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=Object.defineProperties,i=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,s=Object.prototype.propertyIsEnumerable,c=(t,i,n)=>i in t?e(t,i,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[i]=n,o=(e,t)=>{for(var i in t||(t={}))r.call(t,i)&&c(e,i,t[i]);if(n)for(var i of n(t))s.call(t,i)&&c(e,i,t[i]);return e},a=(e,t,i)=>new Promise((n,r)=>{var s=e=>{try{o(i.next(e))}catch(t){r(t)}},c=e=>{try{o(i.throw(e))}catch(t){r(t)}},o=e=>e.done?n(e.value):Promise.resolve(e.value).then(s,c);o((i=i.apply(e,t)).next())});import{L as l,B as u,z as h,C as d,P as v,A as f,D as g,F as C}from"./shared-DuaS72fL.js";const D={defaultChunkSize:50,defaultDelay:20,defaultRetries:3,minChunkSize:10,maxChunkSize:256,maxDelay:200,successThreshold:3,failureThreshold:2,connectionCheckInterval:10},p=class e{constructor(e,t={}){this.logger=l.scope(e),this.config=o(o({},D),t)}checkConnection(e){return a(this,null,function*(){})}computeTimeoutMs(t){return Math.max(e.TIMEOUT_BASE_MS,Math.min(e.TIMEOUT_MAX_MS,e.TIMEOUT_BASE_MS+t*e.TIMEOUT_PER_BYTE_MS))}getMaxChunkSize(e){return this.config.maxChunkSize}execute(e,t){return a(this,arguments,function*(e,t,i={},n){const r=new Uint8Array(e);if(0===r.length)return void this.logger.warn("No data to write");const s=this.initializeTransmissionParams(r,i),c=this.getMaxChunkSize(t.deviceId),o={successCount:0,consecutiveFailures:0,currentChunkSize:s.chunkSize,baseDelay:s.delay};this.logger.debug(`Writing ${r.length} bytes with initial chunkSize=${o.currentChunkSize}, delay=${o.baseDelay}ms`);for(let a=0;a<r.length;a+=o.currentChunkSize){yield this.maybeCheckConnection(a,o.currentChunkSize,t.deviceId);const e=Math.floor(a/o.currentChunkSize)+1,i=yield this.writeChunkWithRetries(r,a,o.currentChunkSize,t,e,s.retries,o.baseDelay,n);if(!i)return;this.adjustTransmissionParams(o,i,c,s.minChunkSize,s.maxDelay,s.successThreshold,s.failureThreshold,e,a,r.length),yield this.maybeDelay(a,o.currentChunkSize,r.length,o.baseDelay)}this.logger.info(`Successfully wrote ${r.length} bytes`)})}initializeTransmissionParams(e,t){var i,n,r;return{chunkSize:Math.max(1,Math.min(256,null!=(i=t.chunkSize)?i:this.config.defaultChunkSize)),delay:Math.max(10,Math.min(100,null!=(n=t.delay)?n:this.config.defaultDelay)),retries:Math.max(1,Math.min(10,null!=(r=t.retries)?r:this.config.defaultRetries)),minChunkSize:this.config.minChunkSize,maxDelay:this.config.maxDelay,successThreshold:this.config.successThreshold,failureThreshold:this.config.failureThreshold}}maybeCheckConnection(e,t,i){return a(this,null,function*(){e>0&&Math.floor(e/t)%this.config.connectionCheckInterval===0&&(yield this.checkConnection(i))})}writeChunkWithRetries(e,t,i,n,r,s,c,o){return a(this,null,function*(){var a;const l=e.slice(t,t+i),d=Math.ceil(e.length/i);for(let e=0;s>=e;e++){const t=yield this.writeSingleChunk(l,n,o);if(t.success)return this.logger.debug(`Chunk ${r}/${d} written successfully`),!0;if(e>=s)throw this.logger.error(`Chunk ${r} failed after ${s} retries`),new u(h.WRITE_FAILED,`Failed to write chunk ${r}/${d}`,null!=(a=t.error)?a:Error("Unknown write error"));this.logger.warn(`Chunk ${r} write failed, retry ${e+1}/${s}`);const i=c*Math.pow(2,e);yield new Promise(e=>setTimeout(e,Math.min(i,this.config.maxDelay)))}return!1})}adjustTransmissionParams(t,i,n,r,s,c,o,a,l,u){i?(t.successCount++,t.consecutiveFailures=0,t.successCount%c===0&&t.currentChunkSize<n&&(t.currentChunkSize=Math.min(n,t.currentChunkSize+e.CHUNK_SIZE_STEP),t.baseDelay=Math.max(t.baseDelay/e.DELAY_RECOVERY_FACTOR,this.config.defaultDelay),this.logger.debug(`Increased chunk size to ${t.currentChunkSize}, delay to ${t.baseDelay}ms`))):(t.consecutiveFailures++,t.consecutiveFailures>=o&&t.currentChunkSize>r&&(t.currentChunkSize=Math.max(r,t.currentChunkSize-e.CHUNK_SIZE_STEP),t.baseDelay=Math.min(t.baseDelay*e.DELAY_BACKOFF_FACTOR,s),this.logger.debug(`Decreased chunk size to ${t.currentChunkSize}, delay to ${t.baseDelay}ms`),t.consecutiveFailures=0))}maybeDelay(e,t,i,n){return a(this,null,function*(){i>e+t&&(yield new Promise(e=>setTimeout(e,n)))})}};p.CHUNK_SIZE_STEP=5,p.DELAY_BACKOFF_FACTOR=1.5,p.DELAY_RECOVERY_FACTOR=1.2,p.TIMEOUT_BASE_MS=1e3,p.TIMEOUT_PER_BYTE_MS=5,p.TIMEOUT_MAX_MS=1e4;let m=p;class I extends m{constructor(e){var n;super("MiniProgramAdapter",(n=o({},D),t(n,i({connectionCheckInterval:5})))),this.api=e}writeSingleChunk(e,t){return a(this,null,function*(){const i=this.computeTimeoutMs(e.length);try{const n=this.api.writeBLECharacteristicValue({deviceId:t.deviceId,serviceId:t.serviceId,characteristicId:t.characteristicId,value:e.buffer});let r;const s=new Promise((e,t)=>{r=setTimeout(()=>{t(Error(`Write timeout after ${i}ms`))},i)});return yield Promise.race([n,s]),r&&clearTimeout(r),{success:!0}}catch(n){return{success:!1,error:d(n)}}})}checkConnection(e){return a(this,null,function*(){try{if(!(yield this.api.getBLEConnectionState({deviceId:e})).connected)throw new u(h.DEVICE_DISCONNECTED,"Device disconnected")}catch(t){if(t instanceof u)throw t;throw new u(h.DEVICE_DISCONNECTED,"Device disconnected",d(t))}})}}class w{constructor(){this.serviceCache=/* @__PURE__ */new Map,this.logger=l.scope("BaseAdapter")}onStateChange(e){this.stateCallback=e}updateState(e){this.stateCallback&&this.stateCallback(e)}validateDeviceId(e){if(!e||"string"!=typeof e)throw new u(h.DEVICE_NOT_FOUND,"Invalid device ID provided")}validateBuffer(e){if(!(e&&e instanceof ArrayBuffer))throw new u(h.PRINT_JOB_FAILED,"Invalid buffer data provided")}validateOptions(e){var t,i,n;return{chunkSize:Math.max(1,Math.min(256,null!=(t=null==e?void 0:e.chunkSize)?t:20)),delay:Math.max(10,Math.min(100,null!=(i=null==e?void 0:e.delay)?i:20)),retries:Math.max(1,Math.min(10,null!=(n=null==e?void 0:e.retries)?n:3))}}getServiceInfo(e){const t=this.serviceCache.get(e);if(!t)throw new u(h.SERVICE_NOT_FOUND,"Device not connected or services not discovered. Call connect() first.");return t}isDeviceConnected(e){return this.serviceCache.has(e)}cleanupDevice(e){this.serviceCache.delete(e)}classifyConnectionError(e,t){const i=d(e).message;return i.includes("timeout")?new u(h.CONNECTION_TIMEOUT,`Connection to device ${t} timed out`,d(e)):i.includes("not found")||i.includes("not exist")?new u(h.DEVICE_NOT_FOUND,`Device ${t} not found`,d(e)):new u(h.CONNECTION_FAILED,"Failed to connect to device "+t,d(e))}discoverAndCacheServices(e,t){return a(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const i=yield t();for(const t of i){const i=t.characteristics.find(e=>e.isWritable);if(i)return this.serviceCache.set(e,{serviceId:t.serviceId,characteristicId:i.characteristicId}),void this.logger.info("Found writeable characteristic:",{service:t.serviceId,characteristic:i.characteristicId})}throw new u(h.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(i){if(i instanceof u)throw i;throw new u(h.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",d(i))}})}destroy(){this.logger.debug("Destroying BaseAdapter"),this.serviceCache.clear(),this.stateCallback=void 0}}class E extends w{constructor(){super(...arguments),this.writeStrategy=null}getWriteStrategy(){return this.writeStrategy||(this.writeStrategy=new I(this.getApi())),this.writeStrategy}connect(e){return a(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(v.CONNECTED);this.updateState(v.CONNECTING),this.logger.debug("Connecting to device:",e);try{yield f(this.getApi().createBLEConnection({deviceId:e}),1e4,"Connection timeout after 10 seconds"),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(v.CONNECTED),this.logger.info("Device connected successfully"),this.getApi().onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(v.DISCONNECTED),this.cleanupDevice(e))})}catch(t){throw this.updateState(v.DISCONNECTED),this.logger.error("Connection failed:",t),this.classifyConnectionError(t,e)}})}finalizeDisconnect(e){this.cleanupDevice(e),this.updateState(v.DISCONNECTED),this.logger.info("Device disconnected successfully")}disconnect(e){return a(this,null,function*(){this.validateDeviceId(e),this.updateState(v.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield this.getApi().closeBLEConnection({deviceId:e}),this.finalizeDisconnect(e)}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.finalizeDisconnect(e)}})}write(e,t,i){return a(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.getServiceInfo(e);yield this.getWriteStrategy().execute(t,{deviceId:e,serviceId:n.serviceId,characteristicId:n.characteristicId},null!=i?i:{})})}discoverServices(e){return a(this,null,function*(){yield this.discoverAndCacheServices(e,()=>a(this,null,function*(){const t=yield this.getApi().getBLEDeviceServices({deviceId:e}),i=[];for(const n of t.services){const t=yield this.getApi().getBLEDeviceCharacteristics({deviceId:e,serviceId:n.uuid});i.push({serviceId:n.uuid,characteristics:t.characteristics.map(e=>({characteristicId:e.uuid,isWritable:!(!e.properties.write&&!e.properties.writeWithoutResponse)}))})}return i}))})}}class y extends E{getApi(){return Taro}}class S extends E{getApi(){return my}}class T extends E{getApi(){return swan}}class O extends E{getApi(){return tt}}class N extends E{getApi(){return qq}}const b=["000018f0-0000-1000-8000-00805f9b34fb","49535343-fe7d-4ae5-8fa9-9fafd205e455","e7810a71-73ae-499d-8c15-faa9aef0c3f2"];class A extends w{constructor(){super(...arguments),this.devices=/* @__PURE__ */new Map,this.discoveredDevices=/* @__PURE__ */new Map,this.connectionCleanupTimeout=null}static isSupported(){return"undefined"!=typeof navigator&&void 0!==navigator.bluetooth&&"function"==typeof navigator.bluetooth.requestDevice}requestDevice(e){return a(this,null,function*(){if(!A.isSupported())throw new u(h.PLATFORM_NOT_SUPPORTED,"Web Bluetooth API is not supported in this browser");this.logger.debug("Requesting Bluetooth device");try{const t=this.buildRequestOptions(e),i=yield navigator.bluetooth.requestDevice(t);return this.logger.info("Device selected:",i.name||i.id),i}catch(t){const e=d(t).message;if(e.includes("cancelled")||e.includes("canceled"))throw new u(h.CONNECTION_FAILED,"User cancelled device selection");if(e.includes("permission")||e.includes("denied"))throw new u(h.CONNECTION_FAILED,"Bluetooth permission denied");throw new u(h.CONNECTION_FAILED,"Failed to request Bluetooth device",d(t))}})}connect(e){return a(this,null,function*(){var t;if(this.validateDeviceId(e),this.devices.has(e)){const t=this.devices.get(e);if(null==t?void 0:t.server.connected)return this.logger.warn("Device already connected:",e),void this.updateState(v.CONNECTED);this.cleanupDeviceInfo(e)}this.updateState(v.CONNECTING),this.logger.debug("Connecting to device:",e);try{const n=yield this.getOrRequestDevice(e);if(!n.gatt)throw new u(h.CONNECTION_FAILED,"Device does not support GATT");const r=yield this.connectWithTimeout(n.gatt,1e4);this.logger.info("GATT server connected");const s=yield this.discoverWriteableCharacteristic(r);let c;try{const e=s.service.device;"readRemoteRssi"in e&&"function"==typeof e.readRemoteRssi&&(c=yield e.readRemoteRssi())}catch(i){this.logger.debug("RSSI reading not supported on this device")}const o={device:n,server:r,characteristic:s,discoveredAt:Date.now()};void 0!==c&&(o.rssiAtConnection=c),this.devices.set(e,o),this.serviceCache.set(e,{serviceId:(null==(t=s.service)?void 0:t.uuid)||"",characteristicId:s.uuid}),n.addEventListener("gattserverdisconnected",()=>{this.handleDisconnection(e)},{once:!0}),this.updateState(v.CONNECTED),this.logger.info("Device connected successfully")}catch(n){if(this.updateState(v.DISCONNECTED),this.logger.error("Connection failed:",n),n instanceof u)throw n;if(d(n).message.includes("timeout"))throw new u(h.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,d(n));throw new u(h.CONNECTION_FAILED,"Failed to connect to device "+e,d(n))}})}disconnect(e){return a(this,null,function*(){var t;yield Promise.resolve(),this.validateDeviceId(e);const i=this.devices.get(e);if(i){this.updateState(v.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null),(null==(t=null==i?void 0:i.server)?void 0:t.connected)&&(i.server.disconnect(),this.logger.debug("GATT server disconnected"))}catch(n){this.logger.warn("Disconnect error:",n)}finally{this.cleanupDeviceInfo(e),this.updateState(v.DISCONNECTED),this.logger.info("Device disconnected successfully")}}else this.logger.debug("Device not found in cache, nothing to disconnect")})}write(e,t,i){return a(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.devices.get(e);if(!n)throw new u(h.DEVICE_DISCONNECTED,"Device not connected. Call connect() first.");if(!n.server.connected)throw this.cleanupDeviceInfo(e),new u(h.DEVICE_DISCONNECTED,"Device disconnected");const r=this.validateOptions(i),{chunkSize:s,delay:c,retries:o}=r,a=new Uint8Array(t),l=Math.ceil(a.length/s);if(this.logger.debug(`Writing ${a.length} bytes in ${l} chunks`),0!==a.length){for(let t=0;t<a.length;t+=s){const i=a.slice(t,t+s),r=Math.floor(t/s)+1;let f=0;for(;o>=f;)try{if(!n.server.connected)throw this.cleanupDeviceInfo(e),new u(h.DEVICE_DISCONNECTED,"Device disconnected");yield n.characteristic.writeValueWithoutResponse(i.buffer),this.logger.debug(`Chunk ${r}/${l} written successfully`);break}catch(v){if(f++,f>o)throw this.logger.error(`Chunk ${r} failed after ${o} retries`),new u(h.WRITE_FAILED,`Failed to write chunk ${r}/${l}`,d(v));this.logger.warn(`Chunk ${r} write failed, retry ${f}/${o}`),yield new Promise(e=>setTimeout(e,c*f))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,c)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}getDeviceId(e){if(!e)throw new u(h.DEVICE_NOT_FOUND,"Device is required");return e.id||this.generateFallbackDeviceId(e)}getDeviceInfo(e){const t=this.devices.get(e);if(!t)return null;const i={deviceId:e,name:t.device.name||"Unknown Device",connected:t.server.connected};return void 0!==t.rssiAtConnection&&(i.rssi=t.rssiAtConnection),i}filterDevices(e,t){return e.filter(e=>{if(void 0!==t.minRSSI&&(void 0===e.rssi||e.rssi<t.minRSSI))return!1;if(void 0!==t.maxRSSI&&(void 0===e.rssi||e.rssi>t.maxRSSI))return!1;if(t.namePrefix&&!e.name.toLowerCase().startsWith(t.namePrefix.toLowerCase()))return!1;if(t.name){const i=t.name.toLowerCase();if(!e.name.toLowerCase().includes(i))return!1}if(t.serviceUUIDs&&t.serviceUUIDs.length>0){const i=e.device,n=Array.from(i.uuids||[]);if(!t.serviceUUIDs.some(e=>n.some(t=>t.toLowerCase()===e.toLowerCase())))return!1}return!0})}sortByRSSI(e,t=!1){return[...e].sort((e,i)=>{var n,r;const s=null!=(n=e.rssi)?n:-1/0,c=null!=(r=i.rssi)?r:-1/0;return t?s-c:c-s})}buildRequestOptions(e){var t,i;const n=[];if(null==e?void 0:e.acceptAllDevices)return{acceptAllDevices:!0,optionalServices:e.optionalServices||b};if((null==(t=null==e?void 0:e.serviceUUIDs)?void 0:t.length)&&n.push({services:e.serviceUUIDs}),(null==e?void 0:e.namePrefix)&&n.push({namePrefix:e.namePrefix}),(null==e?void 0:e.name)&&n.push({name:e.name}),null==(i=null==e?void 0:e.manufacturerDataFilter)?void 0:i.length)for(const r of e.manufacturerDataFilter){const e={manufacturerData:[{companyIdentifier:r.companyIdentifier}]};n.push(e)}return 0===n.length?{acceptAllDevices:!0,optionalServices:(null==e?void 0:e.optionalServices)||b}:{filters:n,optionalServices:(null==e?void 0:e.optionalServices)||b}}getOrRequestDevice(e){return a(this,null,function*(){const t=this.devices.get(e);if(null==t?void 0:t.device)return t.device;const i=this.discoveredDevices.get(e);return(null==i?void 0:i.device)?i.device:this.requestDevice()})}connectWithTimeout(e,t){return a(this,null,function*(){return new Promise((i,n)=>{const r=setTimeout(()=>{n(Error("Connection timeout"))},t);e.connect().then(e=>{clearTimeout(r),i(e)}).catch(e=>{clearTimeout(r),n(d(e))})})})}discoverWriteableCharacteristic(e){return a(this,null,function*(){this.logger.debug("Discovering services");try{const i=yield e.getPrimaryServices();for(const e of i)try{const t=yield e.getCharacteristics();for(const i of t)if(i.properties.write||i.properties.writeWithoutResponse)return this.logger.info("Found writeable characteristic:",{service:e.uuid,characteristic:i.uuid}),i}catch(t){this.logger.debug(`Failed to get characteristics for service ${e.uuid}:`,t)}throw new u(h.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof u)throw t;throw new u(h.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",d(t))}})}handleDisconnection(e){this.logger.warn("Device disconnected unexpectedly:",e),this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null),this.cleanupDeviceInfo(e),this.updateState(v.DISCONNECTED)}cleanupDeviceInfo(e){this.devices.delete(e),this.cleanupDevice(e)}generateFallbackDeviceId(e){return`fallback_${e.name||"unknown"}_${Date.now().toString(36)}`}destroy(){this.logger.debug("Destroying WebBluetoothAdapter"),this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null);for(const[t,i]of this.devices)try{i.server.connected&&i.server.disconnect()}catch(e){this.logger.warn(`Error disconnecting device ${t}:`,e)}this.devices.clear(),this.discoveredDevices.clear(),super.destroy(),this.logger.info("WebBluetoothAdapter destroyed")}}const _=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,WebBluetoothAdapter:A},Symbol.toStringTag,{value:"Module"}));class k{static create(){return this.createForPlatform(g())}static createForPlatform(e){switch(e){case C.WECHAT:return new y;case C.ALIPAY:return new S;case C.BAIDU:return new T;case C.BYTEDANCE:return new O;case C.QQ:return new N;case C.WEB:if(A.isSupported())return new A;throw new u(h.PLATFORM_NOT_SUPPORTED,"Web Bluetooth API is not supported in this browser. Please use a supported browser (Chrome, Edge, Opera).");default:throw new u(h.PLATFORM_NOT_SUPPORTED,`Platform ${e} is not supported. Please use a supported mini-program platform.`)}}}export{k as A,w as B,m as C,D,E as M,N as Q,y as T,A as W,S as a,T as b,O as c,_ as d};
|
|
1
|
+
var e=Object.defineProperty,t=Object.defineProperties,i=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,s=Object.prototype.propertyIsEnumerable,c=(t,i,n)=>i in t?e(t,i,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[i]=n,o=(e,t)=>{for(var i in t||(t={}))r.call(t,i)&&c(e,i,t[i]);if(n)for(var i of n(t))s.call(t,i)&&c(e,i,t[i]);return e},a=(e,t,i)=>new Promise((n,r)=>{var s=e=>{try{o(i.next(e))}catch(t){r(t)}},c=e=>{try{o(i.throw(e))}catch(t){r(t)}},o=e=>e.done?n(e.value):Promise.resolve(e.value).then(s,c);o((i=i.apply(e,t)).next())});import{L as l,B as u,n as h,o as d,P as v,w as f,p as g,q as C}from"./shared-C7eA759x.js";const D={defaultChunkSize:50,defaultDelay:20,defaultRetries:3,minChunkSize:10,maxChunkSize:256,maxDelay:200,successThreshold:3,failureThreshold:2,connectionCheckInterval:10},p=class e{constructor(e,t={}){this.logger=l.scope(e),this.config=o(o({},D),t)}checkConnection(e){return a(this,null,function*(){})}computeTimeoutMs(t){return Math.max(e.TIMEOUT_BASE_MS,Math.min(e.TIMEOUT_MAX_MS,e.TIMEOUT_BASE_MS+t*e.TIMEOUT_PER_BYTE_MS))}getMaxChunkSize(e){return this.config.maxChunkSize}execute(e,t){return a(this,arguments,function*(e,t,i={},n){const r=new Uint8Array(e);if(0===r.length)return void this.logger.warn("No data to write");const s=this.initializeTransmissionParams(r,i),c=this.getMaxChunkSize(t.deviceId),o={successCount:0,consecutiveFailures:0,currentChunkSize:s.chunkSize,baseDelay:s.delay};this.logger.debug(`Writing ${r.length} bytes with initial chunkSize=${o.currentChunkSize}, delay=${o.baseDelay}ms`);for(let a=0;a<r.length;a+=o.currentChunkSize){yield this.maybeCheckConnection(a,o.currentChunkSize,t.deviceId);const e=Math.floor(a/o.currentChunkSize)+1,i=yield this.writeChunkWithRetries(r,a,o.currentChunkSize,t,e,s.retries,o.baseDelay,n);if(!i)return;this.adjustTransmissionParams(o,i,c,s.minChunkSize,s.maxDelay,s.successThreshold,s.failureThreshold,e,a,r.length),yield this.maybeDelay(a,o.currentChunkSize,r.length,o.baseDelay)}this.logger.info(`Successfully wrote ${r.length} bytes`)})}initializeTransmissionParams(e,t){var i,n,r;return{chunkSize:Math.max(1,Math.min(256,null!=(i=t.chunkSize)?i:this.config.defaultChunkSize)),delay:Math.max(10,Math.min(100,null!=(n=t.delay)?n:this.config.defaultDelay)),retries:Math.max(1,Math.min(10,null!=(r=t.retries)?r:this.config.defaultRetries)),minChunkSize:this.config.minChunkSize,maxDelay:this.config.maxDelay,successThreshold:this.config.successThreshold,failureThreshold:this.config.failureThreshold}}maybeCheckConnection(e,t,i){return a(this,null,function*(){e>0&&Math.floor(e/t)%this.config.connectionCheckInterval===0&&(yield this.checkConnection(i))})}writeChunkWithRetries(e,t,i,n,r,s,c,o){return a(this,null,function*(){var a;const l=e.slice(t,t+i),d=Math.ceil(e.length/i);for(let e=0;s>=e;e++){const t=yield this.writeSingleChunk(l,n,o);if(t.success)return this.logger.debug(`Chunk ${r}/${d} written successfully`),!0;if(e>=s)throw this.logger.error(`Chunk ${r} failed after ${s} retries`),new u(h.WRITE_FAILED,`Failed to write chunk ${r}/${d}`,null!=(a=t.error)?a:Error("Unknown write error"));this.logger.warn(`Chunk ${r} write failed, retry ${e+1}/${s}`);const i=c*Math.pow(2,e);yield new Promise(e=>setTimeout(e,Math.min(i,this.config.maxDelay)))}return!1})}adjustTransmissionParams(t,i,n,r,s,c,o,a,l,u){i?(t.successCount++,t.consecutiveFailures=0,t.successCount%c===0&&t.currentChunkSize<n&&(t.currentChunkSize=Math.min(n,t.currentChunkSize+e.CHUNK_SIZE_STEP),t.baseDelay=Math.max(t.baseDelay/e.DELAY_RECOVERY_FACTOR,this.config.defaultDelay),this.logger.debug(`Increased chunk size to ${t.currentChunkSize}, delay to ${t.baseDelay}ms`))):(t.consecutiveFailures++,t.consecutiveFailures>=o&&t.currentChunkSize>r&&(t.currentChunkSize=Math.max(r,t.currentChunkSize-e.CHUNK_SIZE_STEP),t.baseDelay=Math.min(t.baseDelay*e.DELAY_BACKOFF_FACTOR,s),this.logger.debug(`Decreased chunk size to ${t.currentChunkSize}, delay to ${t.baseDelay}ms`),t.consecutiveFailures=0))}maybeDelay(e,t,i,n){return a(this,null,function*(){i>e+t&&(yield new Promise(e=>setTimeout(e,n)))})}};p.CHUNK_SIZE_STEP=5,p.DELAY_BACKOFF_FACTOR=1.5,p.DELAY_RECOVERY_FACTOR=1.2,p.TIMEOUT_BASE_MS=1e3,p.TIMEOUT_PER_BYTE_MS=5,p.TIMEOUT_MAX_MS=1e4;let m=p;class I extends m{constructor(e){var n;super("MiniProgramAdapter",(n=o({},D),t(n,i({connectionCheckInterval:5})))),this.api=e}writeSingleChunk(e,t){return a(this,null,function*(){const i=this.computeTimeoutMs(e.length);try{const n=this.api.writeBLECharacteristicValue({deviceId:t.deviceId,serviceId:t.serviceId,characteristicId:t.characteristicId,value:e.buffer});let r;const s=new Promise((e,t)=>{r=setTimeout(()=>{t(Error(`Write timeout after ${i}ms`))},i)});return yield Promise.race([n,s]),r&&clearTimeout(r),{success:!0}}catch(n){return{success:!1,error:d(n)}}})}checkConnection(e){return a(this,null,function*(){try{if(!(yield this.api.getBLEConnectionState({deviceId:e})).connected)throw new u(h.DEVICE_DISCONNECTED,"Device disconnected")}catch(t){if(t instanceof u)throw t;throw new u(h.DEVICE_DISCONNECTED,"Device disconnected",d(t))}})}}class w{constructor(){this.serviceCache=/* @__PURE__ */new Map,this.logger=l.scope("BaseAdapter")}onStateChange(e){this.stateCallback=e}updateState(e){this.stateCallback&&this.stateCallback(e)}validateDeviceId(e){if(!e||"string"!=typeof e)throw new u(h.DEVICE_NOT_FOUND,"Invalid device ID provided")}validateBuffer(e){if(!(e&&e instanceof ArrayBuffer))throw new u(h.PRINT_JOB_FAILED,"Invalid buffer data provided")}validateOptions(e){var t,i,n;return{chunkSize:Math.max(1,Math.min(256,null!=(t=null==e?void 0:e.chunkSize)?t:20)),delay:Math.max(10,Math.min(100,null!=(i=null==e?void 0:e.delay)?i:20)),retries:Math.max(1,Math.min(10,null!=(n=null==e?void 0:e.retries)?n:3))}}getServiceInfo(e){const t=this.serviceCache.get(e);if(!t)throw new u(h.SERVICE_NOT_FOUND,"Device not connected or services not discovered. Call connect() first.");return t}isDeviceConnected(e){return this.serviceCache.has(e)}cleanupDevice(e){this.serviceCache.delete(e)}classifyConnectionError(e,t){const i=d(e).message;return i.includes("timeout")?new u(h.CONNECTION_TIMEOUT,`Connection to device ${t} timed out`,d(e)):i.includes("not found")||i.includes("not exist")?new u(h.DEVICE_NOT_FOUND,`Device ${t} not found`,d(e)):new u(h.CONNECTION_FAILED,"Failed to connect to device "+t,d(e))}discoverAndCacheServices(e,t){return a(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const i=yield t();for(const t of i){const i=t.characteristics.find(e=>e.isWritable);if(i)return this.serviceCache.set(e,{serviceId:t.serviceId,characteristicId:i.characteristicId}),void this.logger.info("Found writeable characteristic:",{service:t.serviceId,characteristic:i.characteristicId})}throw new u(h.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(i){if(i instanceof u)throw i;throw new u(h.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",d(i))}})}destroy(){this.logger.debug("Destroying BaseAdapter"),this.serviceCache.clear(),this.stateCallback=void 0}}class E extends w{constructor(){super(...arguments),this.writeStrategy=null}getWriteStrategy(){return this.writeStrategy||(this.writeStrategy=new I(this.getApi())),this.writeStrategy}connect(e){return a(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(v.CONNECTED);this.updateState(v.CONNECTING),this.logger.debug("Connecting to device:",e);try{yield f(this.getApi().createBLEConnection({deviceId:e}),1e4,"Connection timeout after 10 seconds"),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(v.CONNECTED),this.logger.info("Device connected successfully"),this.getApi().onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(v.DISCONNECTED),this.cleanupDevice(e))})}catch(t){throw this.updateState(v.DISCONNECTED),this.logger.error("Connection failed:",t),this.classifyConnectionError(t,e)}})}finalizeDisconnect(e){this.cleanupDevice(e),this.updateState(v.DISCONNECTED),this.logger.info("Device disconnected successfully")}disconnect(e){return a(this,null,function*(){this.validateDeviceId(e),this.updateState(v.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield this.getApi().closeBLEConnection({deviceId:e}),this.finalizeDisconnect(e)}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.finalizeDisconnect(e)}})}write(e,t,i){return a(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.getServiceInfo(e);yield this.getWriteStrategy().execute(t,{deviceId:e,serviceId:n.serviceId,characteristicId:n.characteristicId},null!=i?i:{})})}discoverServices(e){return a(this,null,function*(){yield this.discoverAndCacheServices(e,()=>a(this,null,function*(){const t=yield this.getApi().getBLEDeviceServices({deviceId:e}),i=[];for(const n of t.services){const t=yield this.getApi().getBLEDeviceCharacteristics({deviceId:e,serviceId:n.uuid});i.push({serviceId:n.uuid,characteristics:t.characteristics.map(e=>({characteristicId:e.uuid,isWritable:!(!e.properties.write&&!e.properties.writeWithoutResponse)}))})}return i}))})}}class y extends E{getApi(){return Taro}}class S extends E{getApi(){return my}}class T extends E{getApi(){return swan}}class O extends E{getApi(){return tt}}class N extends E{getApi(){return qq}}const b=["000018f0-0000-1000-8000-00805f9b34fb","49535343-fe7d-4ae5-8fa9-9fafd205e455","e7810a71-73ae-499d-8c15-faa9aef0c3f2"];class _ extends w{constructor(){super(...arguments),this.devices=/* @__PURE__ */new Map,this.discoveredDevices=/* @__PURE__ */new Map,this.connectionCleanupTimeout=null}static isSupported(){return"undefined"!=typeof navigator&&void 0!==navigator.bluetooth&&"function"==typeof navigator.bluetooth.requestDevice}requestDevice(e){return a(this,null,function*(){if(!_.isSupported())throw new u(h.PLATFORM_NOT_SUPPORTED,"Web Bluetooth API is not supported in this browser");this.logger.debug("Requesting Bluetooth device");try{const t=this.buildRequestOptions(e),i=yield navigator.bluetooth.requestDevice(t);return this.logger.info("Device selected:",i.name||i.id),i}catch(t){const e=d(t).message;if(e.includes("cancelled")||e.includes("canceled"))throw new u(h.CONNECTION_FAILED,"User cancelled device selection");if(e.includes("permission")||e.includes("denied"))throw new u(h.CONNECTION_FAILED,"Bluetooth permission denied");throw new u(h.CONNECTION_FAILED,"Failed to request Bluetooth device",d(t))}})}connect(e){return a(this,null,function*(){var t;if(this.validateDeviceId(e),this.devices.has(e)){const t=this.devices.get(e);if(null==t?void 0:t.server.connected)return this.logger.warn("Device already connected:",e),void this.updateState(v.CONNECTED);this.cleanupDeviceInfo(e)}this.updateState(v.CONNECTING),this.logger.debug("Connecting to device:",e);try{const n=yield this.getOrRequestDevice(e);if(!n.gatt)throw new u(h.CONNECTION_FAILED,"Device does not support GATT");const r=yield this.connectWithTimeout(n.gatt,1e4);this.logger.info("GATT server connected");const s=yield this.discoverWriteableCharacteristic(r);let c;try{const e=s.service.device;"readRemoteRssi"in e&&"function"==typeof e.readRemoteRssi&&(c=yield e.readRemoteRssi())}catch(i){this.logger.debug("RSSI reading not supported on this device")}const o={device:n,server:r,characteristic:s,discoveredAt:Date.now()};void 0!==c&&(o.rssiAtConnection=c),this.devices.set(e,o),this.serviceCache.set(e,{serviceId:(null==(t=s.service)?void 0:t.uuid)||"",characteristicId:s.uuid}),n.addEventListener("gattserverdisconnected",()=>{this.handleDisconnection(e)},{once:!0}),this.updateState(v.CONNECTED),this.logger.info("Device connected successfully")}catch(n){if(this.updateState(v.DISCONNECTED),this.logger.error("Connection failed:",n),n instanceof u)throw n;if(d(n).message.includes("timeout"))throw new u(h.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,d(n));throw new u(h.CONNECTION_FAILED,"Failed to connect to device "+e,d(n))}})}disconnect(e){return a(this,null,function*(){var t;yield Promise.resolve(),this.validateDeviceId(e);const i=this.devices.get(e);if(i){this.updateState(v.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null),(null==(t=null==i?void 0:i.server)?void 0:t.connected)&&(i.server.disconnect(),this.logger.debug("GATT server disconnected"))}catch(n){this.logger.warn("Disconnect error:",n)}finally{this.cleanupDeviceInfo(e),this.updateState(v.DISCONNECTED),this.logger.info("Device disconnected successfully")}}else this.logger.debug("Device not found in cache, nothing to disconnect")})}write(e,t,i){return a(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.devices.get(e);if(!n)throw new u(h.DEVICE_DISCONNECTED,"Device not connected. Call connect() first.");if(!n.server.connected)throw this.cleanupDeviceInfo(e),new u(h.DEVICE_DISCONNECTED,"Device disconnected");const r=this.validateOptions(i),{chunkSize:s,delay:c,retries:o}=r,a=new Uint8Array(t),l=Math.ceil(a.length/s);if(this.logger.debug(`Writing ${a.length} bytes in ${l} chunks`),0!==a.length){for(let t=0;t<a.length;t+=s){const i=a.slice(t,t+s),r=Math.floor(t/s)+1;let f=0;for(;o>=f;)try{if(!n.server.connected)throw this.cleanupDeviceInfo(e),new u(h.DEVICE_DISCONNECTED,"Device disconnected");yield n.characteristic.writeValueWithoutResponse(i.buffer),this.logger.debug(`Chunk ${r}/${l} written successfully`);break}catch(v){if(f++,f>o)throw this.logger.error(`Chunk ${r} failed after ${o} retries`),new u(h.WRITE_FAILED,`Failed to write chunk ${r}/${l}`,d(v));this.logger.warn(`Chunk ${r} write failed, retry ${f}/${o}`),yield new Promise(e=>setTimeout(e,c*f))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,c)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}getDeviceId(e){if(!e)throw new u(h.DEVICE_NOT_FOUND,"Device is required");return e.id||this.generateFallbackDeviceId(e)}getDeviceInfo(e){const t=this.devices.get(e);if(!t)return null;const i={deviceId:e,name:t.device.name||"Unknown Device",connected:t.server.connected};return void 0!==t.rssiAtConnection&&(i.rssi=t.rssiAtConnection),i}filterDevices(e,t){return e.filter(e=>{if(void 0!==t.minRSSI&&(void 0===e.rssi||e.rssi<t.minRSSI))return!1;if(void 0!==t.maxRSSI&&(void 0===e.rssi||e.rssi>t.maxRSSI))return!1;if(t.namePrefix&&!e.name.toLowerCase().startsWith(t.namePrefix.toLowerCase()))return!1;if(t.name){const i=t.name.toLowerCase();if(!e.name.toLowerCase().includes(i))return!1}if(t.serviceUUIDs&&t.serviceUUIDs.length>0){const i=e.device,n=Array.from(i.uuids||[]);if(!t.serviceUUIDs.some(e=>n.some(t=>t.toLowerCase()===e.toLowerCase())))return!1}return!0})}sortByRSSI(e,t=!1){return[...e].sort((e,i)=>{var n,r;const s=null!=(n=e.rssi)?n:-1/0,c=null!=(r=i.rssi)?r:-1/0;return t?s-c:c-s})}buildRequestOptions(e){var t,i;const n=[];if(null==e?void 0:e.acceptAllDevices)return{acceptAllDevices:!0,optionalServices:e.optionalServices||b};if((null==(t=null==e?void 0:e.serviceUUIDs)?void 0:t.length)&&n.push({services:e.serviceUUIDs}),(null==e?void 0:e.namePrefix)&&n.push({namePrefix:e.namePrefix}),(null==e?void 0:e.name)&&n.push({name:e.name}),null==(i=null==e?void 0:e.manufacturerDataFilter)?void 0:i.length)for(const r of e.manufacturerDataFilter){const e={manufacturerData:[{companyIdentifier:r.companyIdentifier}]};n.push(e)}return 0===n.length?{acceptAllDevices:!0,optionalServices:(null==e?void 0:e.optionalServices)||b}:{filters:n,optionalServices:(null==e?void 0:e.optionalServices)||b}}getOrRequestDevice(e){return a(this,null,function*(){const t=this.devices.get(e);if(null==t?void 0:t.device)return t.device;const i=this.discoveredDevices.get(e);return(null==i?void 0:i.device)?i.device:this.requestDevice()})}connectWithTimeout(e,t){return a(this,null,function*(){return new Promise((i,n)=>{const r=setTimeout(()=>{n(Error("Connection timeout"))},t);e.connect().then(e=>{clearTimeout(r),i(e)}).catch(e=>{clearTimeout(r),n(d(e))})})})}discoverWriteableCharacteristic(e){return a(this,null,function*(){this.logger.debug("Discovering services");try{const i=yield e.getPrimaryServices();for(const e of i)try{const t=yield e.getCharacteristics();for(const i of t)if(i.properties.write||i.properties.writeWithoutResponse)return this.logger.info("Found writeable characteristic:",{service:e.uuid,characteristic:i.uuid}),i}catch(t){this.logger.debug(`Failed to get characteristics for service ${e.uuid}:`,t)}throw new u(h.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof u)throw t;throw new u(h.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",d(t))}})}handleDisconnection(e){this.logger.warn("Device disconnected unexpectedly:",e),this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null),this.cleanupDeviceInfo(e),this.updateState(v.DISCONNECTED)}cleanupDeviceInfo(e){this.devices.delete(e),this.cleanupDevice(e)}generateFallbackDeviceId(e){return`fallback_${e.name||"unknown"}_${Date.now().toString(36)}`}destroy(){this.logger.debug("Destroying WebBluetoothAdapter"),this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null);for(const[t,i]of this.devices)try{i.server.connected&&i.server.disconnect()}catch(e){this.logger.warn(`Error disconnecting device ${t}:`,e)}this.devices.clear(),this.discoveredDevices.clear(),super.destroy(),this.logger.info("WebBluetoothAdapter destroyed")}}const A=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,WebBluetoothAdapter:_},Symbol.toStringTag,{value:"Module"}));class k{static create(){return this.createForPlatform(g())}static createForPlatform(e){switch(e){case C.WECHAT:return new y;case C.ALIPAY:return new S;case C.BAIDU:return new T;case C.BYTEDANCE:return new O;case C.QQ:return new N;case C.WEB:if(_.isSupported())return new _;throw new u(h.PLATFORM_NOT_SUPPORTED,"Web Bluetooth API is not supported in this browser. Please use a supported browser (Chrome, Edge, Opera).");default:throw new u(h.PLATFORM_NOT_SUPPORTED,`Platform ${e} is not supported. Please use a supported mini-program platform.`)}}}export{k as A,w as B,m as C,D,E as M,N as Q,y as T,_ as W,S as a,T as b,O as c,A as d};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=Object.defineProperty,t=Object.defineProperties,i=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,s=Object.prototype.propertyIsEnumerable,c=(t,i,n)=>i in t?e(t,i,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[i]=n,o=(e,t)=>{for(var i in t||(t={}))r.call(t,i)&&c(e,i,t[i]);if(n)for(var i of n(t))s.call(t,i)&&c(e,i,t[i]);return e},a=(e,t,i)=>new Promise((n,r)=>{var s=e=>{try{o(i.next(e))}catch(t){r(t)}},c=e=>{try{o(i.throw(e))}catch(t){r(t)}},o=e=>e.done?n(e.value):Promise.resolve(e.value).then(s,c);o((i=i.apply(e,t)).next())});const l=require("./shared-C3EQK7YH.js"),u={defaultChunkSize:50,defaultDelay:20,defaultRetries:3,minChunkSize:10,maxChunkSize:256,maxDelay:200,successThreshold:3,failureThreshold:2,connectionCheckInterval:10},h=class e{constructor(e,t={}){this.logger=l.L.scope(e),this.config=o(o({},u),t)}checkConnection(e){return a(this,null,function*(){})}computeTimeoutMs(t){return Math.max(e.TIMEOUT_BASE_MS,Math.min(e.TIMEOUT_MAX_MS,e.TIMEOUT_BASE_MS+t*e.TIMEOUT_PER_BYTE_MS))}getMaxChunkSize(e){return this.config.maxChunkSize}execute(e,t){return a(this,arguments,function*(e,t,i={},n){const r=new Uint8Array(e);if(0===r.length)return void this.logger.warn("No data to write");const s=this.initializeTransmissionParams(r,i),c=this.getMaxChunkSize(t.deviceId),o={successCount:0,consecutiveFailures:0,currentChunkSize:s.chunkSize,baseDelay:s.delay};this.logger.debug(`Writing ${r.length} bytes with initial chunkSize=${o.currentChunkSize}, delay=${o.baseDelay}ms`);for(let a=0;a<r.length;a+=o.currentChunkSize){yield this.maybeCheckConnection(a,o.currentChunkSize,t.deviceId);const e=Math.floor(a/o.currentChunkSize)+1,i=yield this.writeChunkWithRetries(r,a,o.currentChunkSize,t,e,s.retries,o.baseDelay,n);if(!i)return;this.adjustTransmissionParams(o,i,c,s.minChunkSize,s.maxDelay,s.successThreshold,s.failureThreshold,e,a,r.length),yield this.maybeDelay(a,o.currentChunkSize,r.length,o.baseDelay)}this.logger.info(`Successfully wrote ${r.length} bytes`)})}initializeTransmissionParams(e,t){var i,n,r;return{chunkSize:Math.max(1,Math.min(256,null!=(i=t.chunkSize)?i:this.config.defaultChunkSize)),delay:Math.max(10,Math.min(100,null!=(n=t.delay)?n:this.config.defaultDelay)),retries:Math.max(1,Math.min(10,null!=(r=t.retries)?r:this.config.defaultRetries)),minChunkSize:this.config.minChunkSize,maxDelay:this.config.maxDelay,successThreshold:this.config.successThreshold,failureThreshold:this.config.failureThreshold}}maybeCheckConnection(e,t,i){return a(this,null,function*(){e>0&&Math.floor(e/t)%this.config.connectionCheckInterval===0&&(yield this.checkConnection(i))})}writeChunkWithRetries(e,t,i,n,r,s,c,o){return a(this,null,function*(){var a;const u=e.slice(t,t+i),h=Math.ceil(e.length/i);for(let e=0;s>=e;e++){const t=yield this.writeSingleChunk(u,n,o);if(t.success)return this.logger.debug(`Chunk ${r}/${h} written successfully`),!0;if(e>=s)throw this.logger.error(`Chunk ${r} failed after ${s} retries`),new l.B(l.z.WRITE_FAILED,`Failed to write chunk ${r}/${h}`,null!=(a=t.error)?a:Error("Unknown write error"));this.logger.warn(`Chunk ${r} write failed, retry ${e+1}/${s}`);const i=c*Math.pow(2,e);yield new Promise(e=>setTimeout(e,Math.min(i,this.config.maxDelay)))}return!1})}adjustTransmissionParams(t,i,n,r,s,c,o,a,l,u){i?(t.successCount++,t.consecutiveFailures=0,t.successCount%c===0&&t.currentChunkSize<n&&(t.currentChunkSize=Math.min(n,t.currentChunkSize+e.CHUNK_SIZE_STEP),t.baseDelay=Math.max(t.baseDelay/e.DELAY_RECOVERY_FACTOR,this.config.defaultDelay),this.logger.debug(`Increased chunk size to ${t.currentChunkSize}, delay to ${t.baseDelay}ms`))):(t.consecutiveFailures++,t.consecutiveFailures>=o&&t.currentChunkSize>r&&(t.currentChunkSize=Math.max(r,t.currentChunkSize-e.CHUNK_SIZE_STEP),t.baseDelay=Math.min(t.baseDelay*e.DELAY_BACKOFF_FACTOR,s),this.logger.debug(`Decreased chunk size to ${t.currentChunkSize}, delay to ${t.baseDelay}ms`),t.consecutiveFailures=0))}maybeDelay(e,t,i,n){return a(this,null,function*(){i>e+t&&(yield new Promise(e=>setTimeout(e,n)))})}};h.CHUNK_SIZE_STEP=5,h.DELAY_BACKOFF_FACTOR=1.5,h.DELAY_RECOVERY_FACTOR=1.2,h.TIMEOUT_BASE_MS=1e3,h.TIMEOUT_PER_BYTE_MS=5,h.TIMEOUT_MAX_MS=1e4;let d=h;class v extends d{constructor(e){var n;super("MiniProgramAdapter",(n=o({},u),t(n,i({connectionCheckInterval:5})))),this.api=e}writeSingleChunk(e,t){return a(this,null,function*(){const i=this.computeTimeoutMs(e.length);try{const n=this.api.writeBLECharacteristicValue({deviceId:t.deviceId,serviceId:t.serviceId,characteristicId:t.characteristicId,value:e.buffer});let r;const s=new Promise((e,t)=>{r=setTimeout(()=>{t(Error(`Write timeout after ${i}ms`))},i)});return yield Promise.race([n,s]),r&&clearTimeout(r),{success:!0}}catch(n){return{success:!1,error:l.C(n)}}})}checkConnection(e){return a(this,null,function*(){try{if(!(yield this.api.getBLEConnectionState({deviceId:e})).connected)throw new l.B(l.z.DEVICE_DISCONNECTED,"Device disconnected")}catch(t){if(t instanceof l.B)throw t;throw new l.B(l.z.DEVICE_DISCONNECTED,"Device disconnected",l.C(t))}})}}class g{constructor(){this.serviceCache=new Map,this.logger=l.L.scope("BaseAdapter")}onStateChange(e){this.stateCallback=e}updateState(e){this.stateCallback&&this.stateCallback(e)}validateDeviceId(e){if(!e||"string"!=typeof e)throw new l.B(l.z.DEVICE_NOT_FOUND,"Invalid device ID provided")}validateBuffer(e){if(!(e&&e instanceof ArrayBuffer))throw new l.B(l.z.PRINT_JOB_FAILED,"Invalid buffer data provided")}validateOptions(e){var t,i,n;return{chunkSize:Math.max(1,Math.min(256,null!=(t=null==e?void 0:e.chunkSize)?t:20)),delay:Math.max(10,Math.min(100,null!=(i=null==e?void 0:e.delay)?i:20)),retries:Math.max(1,Math.min(10,null!=(n=null==e?void 0:e.retries)?n:3))}}getServiceInfo(e){const t=this.serviceCache.get(e);if(!t)throw new l.B(l.z.SERVICE_NOT_FOUND,"Device not connected or services not discovered. Call connect() first.");return t}isDeviceConnected(e){return this.serviceCache.has(e)}cleanupDevice(e){this.serviceCache.delete(e)}classifyConnectionError(e,t){const i=l.C(e).message;return i.includes("timeout")?new l.B(l.z.CONNECTION_TIMEOUT,`Connection to device ${t} timed out`,l.C(e)):i.includes("not found")||i.includes("not exist")?new l.B(l.z.DEVICE_NOT_FOUND,`Device ${t} not found`,l.C(e)):new l.B(l.z.CONNECTION_FAILED,"Failed to connect to device "+t,l.C(e))}discoverAndCacheServices(e,t){return a(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const i=yield t();for(const t of i){const i=t.characteristics.find(e=>e.isWritable);if(i)return this.serviceCache.set(e,{serviceId:t.serviceId,characteristicId:i.characteristicId}),void this.logger.info("Found writeable characteristic:",{service:t.serviceId,characteristic:i.characteristicId})}throw new l.B(l.z.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(i){if(i instanceof l.B)throw i;throw new l.B(l.z.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",l.C(i))}})}destroy(){this.logger.debug("Destroying BaseAdapter"),this.serviceCache.clear(),this.stateCallback=void 0}}class f extends g{constructor(){super(...arguments),this.writeStrategy=null}getWriteStrategy(){return this.writeStrategy||(this.writeStrategy=new v(this.getApi())),this.writeStrategy}connect(e){return a(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(l.P.CONNECTED);this.updateState(l.P.CONNECTING),this.logger.debug("Connecting to device:",e);try{yield l.A(this.getApi().createBLEConnection({deviceId:e}),1e4,"Connection timeout after 10 seconds"),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(l.P.CONNECTED),this.logger.info("Device connected successfully"),this.getApi().onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(l.P.DISCONNECTED),this.cleanupDevice(e))})}catch(t){throw this.updateState(l.P.DISCONNECTED),this.logger.error("Connection failed:",t),this.classifyConnectionError(t,e)}})}finalizeDisconnect(e){this.cleanupDevice(e),this.updateState(l.P.DISCONNECTED),this.logger.info("Device disconnected successfully")}disconnect(e){return a(this,null,function*(){this.validateDeviceId(e),this.updateState(l.P.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield this.getApi().closeBLEConnection({deviceId:e}),this.finalizeDisconnect(e)}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.finalizeDisconnect(e)}})}write(e,t,i){return a(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.getServiceInfo(e);yield this.getWriteStrategy().execute(t,{deviceId:e,serviceId:n.serviceId,characteristicId:n.characteristicId},null!=i?i:{})})}discoverServices(e){return a(this,null,function*(){yield this.discoverAndCacheServices(e,()=>a(this,null,function*(){const t=yield this.getApi().getBLEDeviceServices({deviceId:e}),i=[];for(const n of t.services){const t=yield this.getApi().getBLEDeviceCharacteristics({deviceId:e,serviceId:n.uuid});i.push({serviceId:n.uuid,characteristics:t.characteristics.map(e=>({characteristicId:e.uuid,isWritable:!(!e.properties.write&&!e.properties.writeWithoutResponse)}))})}return i}))})}}class C extends f{getApi(){return Taro}}class D extends f{getApi(){return my}}class p extends f{getApi(){return swan}}class m extends f{getApi(){return tt}}class I extends f{getApi(){return qq}}const w=["000018f0-0000-1000-8000-00805f9b34fb","49535343-fe7d-4ae5-8fa9-9fafd205e455","e7810a71-73ae-499d-8c15-faa9aef0c3f2"];class E extends g{constructor(){super(...arguments),this.devices=new Map,this.discoveredDevices=new Map,this.connectionCleanupTimeout=null}static isSupported(){return"undefined"!=typeof navigator&&void 0!==navigator.bluetooth&&"function"==typeof navigator.bluetooth.requestDevice}requestDevice(e){return a(this,null,function*(){if(!E.isSupported())throw new l.B(l.z.PLATFORM_NOT_SUPPORTED,"Web Bluetooth API is not supported in this browser");this.logger.debug("Requesting Bluetooth device");try{const t=this.buildRequestOptions(e),i=yield navigator.bluetooth.requestDevice(t);return this.logger.info("Device selected:",i.name||i.id),i}catch(t){const e=l.C(t).message;if(e.includes("cancelled")||e.includes("canceled"))throw new l.B(l.z.CONNECTION_FAILED,"User cancelled device selection");if(e.includes("permission")||e.includes("denied"))throw new l.B(l.z.CONNECTION_FAILED,"Bluetooth permission denied");throw new l.B(l.z.CONNECTION_FAILED,"Failed to request Bluetooth device",l.C(t))}})}connect(e){return a(this,null,function*(){var t;if(this.validateDeviceId(e),this.devices.has(e)){const t=this.devices.get(e);if(null==t?void 0:t.server.connected)return this.logger.warn("Device already connected:",e),void this.updateState(l.P.CONNECTED);this.cleanupDeviceInfo(e)}this.updateState(l.P.CONNECTING),this.logger.debug("Connecting to device:",e);try{const n=yield this.getOrRequestDevice(e);if(!n.gatt)throw new l.B(l.z.CONNECTION_FAILED,"Device does not support GATT");const r=yield this.connectWithTimeout(n.gatt,1e4);this.logger.info("GATT server connected");const s=yield this.discoverWriteableCharacteristic(r);let c;try{const e=s.service.device;"readRemoteRssi"in e&&"function"==typeof e.readRemoteRssi&&(c=yield e.readRemoteRssi())}catch(i){this.logger.debug("RSSI reading not supported on this device")}const o={device:n,server:r,characteristic:s,discoveredAt:Date.now()};void 0!==c&&(o.rssiAtConnection=c),this.devices.set(e,o),this.serviceCache.set(e,{serviceId:(null==(t=s.service)?void 0:t.uuid)||"",characteristicId:s.uuid}),n.addEventListener("gattserverdisconnected",()=>{this.handleDisconnection(e)},{once:!0}),this.updateState(l.P.CONNECTED),this.logger.info("Device connected successfully")}catch(n){if(this.updateState(l.P.DISCONNECTED),this.logger.error("Connection failed:",n),n instanceof l.B)throw n;if(l.C(n).message.includes("timeout"))throw new l.B(l.z.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,l.C(n));throw new l.B(l.z.CONNECTION_FAILED,"Failed to connect to device "+e,l.C(n))}})}disconnect(e){return a(this,null,function*(){var t;yield Promise.resolve(),this.validateDeviceId(e);const i=this.devices.get(e);if(i){this.updateState(l.P.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null),(null==(t=null==i?void 0:i.server)?void 0:t.connected)&&(i.server.disconnect(),this.logger.debug("GATT server disconnected"))}catch(n){this.logger.warn("Disconnect error:",n)}finally{this.cleanupDeviceInfo(e),this.updateState(l.P.DISCONNECTED),this.logger.info("Device disconnected successfully")}}else this.logger.debug("Device not found in cache, nothing to disconnect")})}write(e,t,i){return a(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.devices.get(e);if(!n)throw new l.B(l.z.DEVICE_DISCONNECTED,"Device not connected. Call connect() first.");if(!n.server.connected)throw this.cleanupDeviceInfo(e),new l.B(l.z.DEVICE_DISCONNECTED,"Device disconnected");const r=this.validateOptions(i),{chunkSize:s,delay:c,retries:o}=r,a=new Uint8Array(t),u=Math.ceil(a.length/s);if(this.logger.debug(`Writing ${a.length} bytes in ${u} chunks`),0!==a.length){for(let t=0;t<a.length;t+=s){const i=a.slice(t,t+s),r=Math.floor(t/s)+1;let d=0;for(;o>=d;)try{if(!n.server.connected)throw this.cleanupDeviceInfo(e),new l.B(l.z.DEVICE_DISCONNECTED,"Device disconnected");yield n.characteristic.writeValueWithoutResponse(i.buffer),this.logger.debug(`Chunk ${r}/${u} written successfully`);break}catch(h){if(d++,d>o)throw this.logger.error(`Chunk ${r} failed after ${o} retries`),new l.B(l.z.WRITE_FAILED,`Failed to write chunk ${r}/${u}`,l.C(h));this.logger.warn(`Chunk ${r} write failed, retry ${d}/${o}`),yield new Promise(e=>setTimeout(e,c*d))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,c)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}getDeviceId(e){if(!e)throw new l.B(l.z.DEVICE_NOT_FOUND,"Device is required");return e.id||this.generateFallbackDeviceId(e)}getDeviceInfo(e){const t=this.devices.get(e);if(!t)return null;const i={deviceId:e,name:t.device.name||"Unknown Device",connected:t.server.connected};return void 0!==t.rssiAtConnection&&(i.rssi=t.rssiAtConnection),i}filterDevices(e,t){return e.filter(e=>{if(void 0!==t.minRSSI&&(void 0===e.rssi||e.rssi<t.minRSSI))return!1;if(void 0!==t.maxRSSI&&(void 0===e.rssi||e.rssi>t.maxRSSI))return!1;if(t.namePrefix&&!e.name.toLowerCase().startsWith(t.namePrefix.toLowerCase()))return!1;if(t.name){const i=t.name.toLowerCase();if(!e.name.toLowerCase().includes(i))return!1}if(t.serviceUUIDs&&t.serviceUUIDs.length>0){const i=e.device,n=Array.from(i.uuids||[]);if(!t.serviceUUIDs.some(e=>n.some(t=>t.toLowerCase()===e.toLowerCase())))return!1}return!0})}sortByRSSI(e,t=!1){return[...e].sort((e,i)=>{var n,r;const s=null!=(n=e.rssi)?n:-1/0,c=null!=(r=i.rssi)?r:-1/0;return t?s-c:c-s})}buildRequestOptions(e){var t,i;const n=[];if(null==e?void 0:e.acceptAllDevices)return{acceptAllDevices:!0,optionalServices:e.optionalServices||w};if((null==(t=null==e?void 0:e.serviceUUIDs)?void 0:t.length)&&n.push({services:e.serviceUUIDs}),(null==e?void 0:e.namePrefix)&&n.push({namePrefix:e.namePrefix}),(null==e?void 0:e.name)&&n.push({name:e.name}),null==(i=null==e?void 0:e.manufacturerDataFilter)?void 0:i.length)for(const r of e.manufacturerDataFilter){const e={manufacturerData:[{companyIdentifier:r.companyIdentifier}]};n.push(e)}return 0===n.length?{acceptAllDevices:!0,optionalServices:(null==e?void 0:e.optionalServices)||w}:{filters:n,optionalServices:(null==e?void 0:e.optionalServices)||w}}getOrRequestDevice(e){return a(this,null,function*(){const t=this.devices.get(e);if(null==t?void 0:t.device)return t.device;const i=this.discoveredDevices.get(e);return(null==i?void 0:i.device)?i.device:this.requestDevice()})}connectWithTimeout(e,t){return a(this,null,function*(){return new Promise((i,n)=>{const r=setTimeout(()=>{n(Error("Connection timeout"))},t);e.connect().then(e=>{clearTimeout(r),i(e)}).catch(e=>{clearTimeout(r),n(l.C(e))})})})}discoverWriteableCharacteristic(e){return a(this,null,function*(){this.logger.debug("Discovering services");try{const i=yield e.getPrimaryServices();for(const e of i)try{const t=yield e.getCharacteristics();for(const i of t)if(i.properties.write||i.properties.writeWithoutResponse)return this.logger.info("Found writeable characteristic:",{service:e.uuid,characteristic:i.uuid}),i}catch(t){this.logger.debug(`Failed to get characteristics for service ${e.uuid}:`,t)}throw new l.B(l.z.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof l.B)throw t;throw new l.B(l.z.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",l.C(t))}})}handleDisconnection(e){this.logger.warn("Device disconnected unexpectedly:",e),this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null),this.cleanupDeviceInfo(e),this.updateState(l.P.DISCONNECTED)}cleanupDeviceInfo(e){this.devices.delete(e),this.cleanupDevice(e)}generateFallbackDeviceId(e){return`fallback_${e.name||"unknown"}_${Date.now().toString(36)}`}destroy(){this.logger.debug("Destroying WebBluetoothAdapter"),this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null);for(const[t,i]of this.devices)try{i.server.connected&&i.server.disconnect()}catch(e){this.logger.warn(`Error disconnecting device ${t}:`,e)}this.devices.clear(),this.discoveredDevices.clear(),super.destroy(),this.logger.info("WebBluetoothAdapter destroyed")}}const y=Object.freeze(Object.defineProperty({__proto__:null,WebBluetoothAdapter:E},Symbol.toStringTag,{value:"Module"}));exports.A=class{static create(){return this.createForPlatform(l.D())}static createForPlatform(e){switch(e){case l.F.WECHAT:return new C;case l.F.ALIPAY:return new D;case l.F.BAIDU:return new p;case l.F.BYTEDANCE:return new m;case l.F.QQ:return new I;case l.F.WEB:if(E.isSupported())return new E;throw new l.B(l.z.PLATFORM_NOT_SUPPORTED,"Web Bluetooth API is not supported in this browser. Please use a supported browser (Chrome, Edge, Opera).");default:throw new l.B(l.z.PLATFORM_NOT_SUPPORTED,`Platform ${e} is not supported. Please use a supported mini-program platform.`)}}},exports.B=g,exports.C=d,exports.D=u,exports.M=f,exports.Q=I,exports.T=C,exports.W=E,exports.a=D,exports.b=p,exports.c=m,exports.d=y;
|
|
1
|
+
"use strict";var e=Object.defineProperty,t=Object.defineProperties,i=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,s=Object.prototype.propertyIsEnumerable,c=(t,i,n)=>i in t?e(t,i,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[i]=n,o=(e,t)=>{for(var i in t||(t={}))r.call(t,i)&&c(e,i,t[i]);if(n)for(var i of n(t))s.call(t,i)&&c(e,i,t[i]);return e},a=(e,t,i)=>new Promise((n,r)=>{var s=e=>{try{o(i.next(e))}catch(t){r(t)}},c=e=>{try{o(i.throw(e))}catch(t){r(t)}},o=e=>e.done?n(e.value):Promise.resolve(e.value).then(s,c);o((i=i.apply(e,t)).next())});const l=require("./shared-CvHoYVGG.js"),u={defaultChunkSize:50,defaultDelay:20,defaultRetries:3,minChunkSize:10,maxChunkSize:256,maxDelay:200,successThreshold:3,failureThreshold:2,connectionCheckInterval:10},h=class e{constructor(e,t={}){this.logger=l.L.scope(e),this.config=o(o({},u),t)}checkConnection(e){return a(this,null,function*(){})}computeTimeoutMs(t){return Math.max(e.TIMEOUT_BASE_MS,Math.min(e.TIMEOUT_MAX_MS,e.TIMEOUT_BASE_MS+t*e.TIMEOUT_PER_BYTE_MS))}getMaxChunkSize(e){return this.config.maxChunkSize}execute(e,t){return a(this,arguments,function*(e,t,i={},n){const r=new Uint8Array(e);if(0===r.length)return void this.logger.warn("No data to write");const s=this.initializeTransmissionParams(r,i),c=this.getMaxChunkSize(t.deviceId),o={successCount:0,consecutiveFailures:0,currentChunkSize:s.chunkSize,baseDelay:s.delay};this.logger.debug(`Writing ${r.length} bytes with initial chunkSize=${o.currentChunkSize}, delay=${o.baseDelay}ms`);for(let a=0;a<r.length;a+=o.currentChunkSize){yield this.maybeCheckConnection(a,o.currentChunkSize,t.deviceId);const e=Math.floor(a/o.currentChunkSize)+1,i=yield this.writeChunkWithRetries(r,a,o.currentChunkSize,t,e,s.retries,o.baseDelay,n);if(!i)return;this.adjustTransmissionParams(o,i,c,s.minChunkSize,s.maxDelay,s.successThreshold,s.failureThreshold,e,a,r.length),yield this.maybeDelay(a,o.currentChunkSize,r.length,o.baseDelay)}this.logger.info(`Successfully wrote ${r.length} bytes`)})}initializeTransmissionParams(e,t){var i,n,r;return{chunkSize:Math.max(1,Math.min(256,null!=(i=t.chunkSize)?i:this.config.defaultChunkSize)),delay:Math.max(10,Math.min(100,null!=(n=t.delay)?n:this.config.defaultDelay)),retries:Math.max(1,Math.min(10,null!=(r=t.retries)?r:this.config.defaultRetries)),minChunkSize:this.config.minChunkSize,maxDelay:this.config.maxDelay,successThreshold:this.config.successThreshold,failureThreshold:this.config.failureThreshold}}maybeCheckConnection(e,t,i){return a(this,null,function*(){e>0&&Math.floor(e/t)%this.config.connectionCheckInterval===0&&(yield this.checkConnection(i))})}writeChunkWithRetries(e,t,i,n,r,s,c,o){return a(this,null,function*(){var a;const u=e.slice(t,t+i),h=Math.ceil(e.length/i);for(let e=0;s>=e;e++){const t=yield this.writeSingleChunk(u,n,o);if(t.success)return this.logger.debug(`Chunk ${r}/${h} written successfully`),!0;if(e>=s)throw this.logger.error(`Chunk ${r} failed after ${s} retries`),new l.B(l.n.WRITE_FAILED,`Failed to write chunk ${r}/${h}`,null!=(a=t.error)?a:Error("Unknown write error"));this.logger.warn(`Chunk ${r} write failed, retry ${e+1}/${s}`);const i=c*Math.pow(2,e);yield new Promise(e=>setTimeout(e,Math.min(i,this.config.maxDelay)))}return!1})}adjustTransmissionParams(t,i,n,r,s,c,o,a,l,u){i?(t.successCount++,t.consecutiveFailures=0,t.successCount%c===0&&t.currentChunkSize<n&&(t.currentChunkSize=Math.min(n,t.currentChunkSize+e.CHUNK_SIZE_STEP),t.baseDelay=Math.max(t.baseDelay/e.DELAY_RECOVERY_FACTOR,this.config.defaultDelay),this.logger.debug(`Increased chunk size to ${t.currentChunkSize}, delay to ${t.baseDelay}ms`))):(t.consecutiveFailures++,t.consecutiveFailures>=o&&t.currentChunkSize>r&&(t.currentChunkSize=Math.max(r,t.currentChunkSize-e.CHUNK_SIZE_STEP),t.baseDelay=Math.min(t.baseDelay*e.DELAY_BACKOFF_FACTOR,s),this.logger.debug(`Decreased chunk size to ${t.currentChunkSize}, delay to ${t.baseDelay}ms`),t.consecutiveFailures=0))}maybeDelay(e,t,i,n){return a(this,null,function*(){i>e+t&&(yield new Promise(e=>setTimeout(e,n)))})}};h.CHUNK_SIZE_STEP=5,h.DELAY_BACKOFF_FACTOR=1.5,h.DELAY_RECOVERY_FACTOR=1.2,h.TIMEOUT_BASE_MS=1e3,h.TIMEOUT_PER_BYTE_MS=5,h.TIMEOUT_MAX_MS=1e4;let d=h;class v extends d{constructor(e){var n;super("MiniProgramAdapter",(n=o({},u),t(n,i({connectionCheckInterval:5})))),this.api=e}writeSingleChunk(e,t){return a(this,null,function*(){const i=this.computeTimeoutMs(e.length);try{const n=this.api.writeBLECharacteristicValue({deviceId:t.deviceId,serviceId:t.serviceId,characteristicId:t.characteristicId,value:e.buffer});let r;const s=new Promise((e,t)=>{r=setTimeout(()=>{t(Error(`Write timeout after ${i}ms`))},i)});return yield Promise.race([n,s]),r&&clearTimeout(r),{success:!0}}catch(n){return{success:!1,error:l.o(n)}}})}checkConnection(e){return a(this,null,function*(){try{if(!(yield this.api.getBLEConnectionState({deviceId:e})).connected)throw new l.B(l.n.DEVICE_DISCONNECTED,"Device disconnected")}catch(t){if(t instanceof l.B)throw t;throw new l.B(l.n.DEVICE_DISCONNECTED,"Device disconnected",l.o(t))}})}}class g{constructor(){this.serviceCache=new Map,this.logger=l.L.scope("BaseAdapter")}onStateChange(e){this.stateCallback=e}updateState(e){this.stateCallback&&this.stateCallback(e)}validateDeviceId(e){if(!e||"string"!=typeof e)throw new l.B(l.n.DEVICE_NOT_FOUND,"Invalid device ID provided")}validateBuffer(e){if(!(e&&e instanceof ArrayBuffer))throw new l.B(l.n.PRINT_JOB_FAILED,"Invalid buffer data provided")}validateOptions(e){var t,i,n;return{chunkSize:Math.max(1,Math.min(256,null!=(t=null==e?void 0:e.chunkSize)?t:20)),delay:Math.max(10,Math.min(100,null!=(i=null==e?void 0:e.delay)?i:20)),retries:Math.max(1,Math.min(10,null!=(n=null==e?void 0:e.retries)?n:3))}}getServiceInfo(e){const t=this.serviceCache.get(e);if(!t)throw new l.B(l.n.SERVICE_NOT_FOUND,"Device not connected or services not discovered. Call connect() first.");return t}isDeviceConnected(e){return this.serviceCache.has(e)}cleanupDevice(e){this.serviceCache.delete(e)}classifyConnectionError(e,t){const i=l.o(e).message;return i.includes("timeout")?new l.B(l.n.CONNECTION_TIMEOUT,`Connection to device ${t} timed out`,l.o(e)):i.includes("not found")||i.includes("not exist")?new l.B(l.n.DEVICE_NOT_FOUND,`Device ${t} not found`,l.o(e)):new l.B(l.n.CONNECTION_FAILED,"Failed to connect to device "+t,l.o(e))}discoverAndCacheServices(e,t){return a(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const i=yield t();for(const t of i){const i=t.characteristics.find(e=>e.isWritable);if(i)return this.serviceCache.set(e,{serviceId:t.serviceId,characteristicId:i.characteristicId}),void this.logger.info("Found writeable characteristic:",{service:t.serviceId,characteristic:i.characteristicId})}throw new l.B(l.n.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(i){if(i instanceof l.B)throw i;throw new l.B(l.n.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",l.o(i))}})}destroy(){this.logger.debug("Destroying BaseAdapter"),this.serviceCache.clear(),this.stateCallback=void 0}}class f extends g{constructor(){super(...arguments),this.writeStrategy=null}getWriteStrategy(){return this.writeStrategy||(this.writeStrategy=new v(this.getApi())),this.writeStrategy}connect(e){return a(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(l.P.CONNECTED);this.updateState(l.P.CONNECTING),this.logger.debug("Connecting to device:",e);try{yield l.w(this.getApi().createBLEConnection({deviceId:e}),1e4,"Connection timeout after 10 seconds"),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(l.P.CONNECTED),this.logger.info("Device connected successfully"),this.getApi().onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(l.P.DISCONNECTED),this.cleanupDevice(e))})}catch(t){throw this.updateState(l.P.DISCONNECTED),this.logger.error("Connection failed:",t),this.classifyConnectionError(t,e)}})}finalizeDisconnect(e){this.cleanupDevice(e),this.updateState(l.P.DISCONNECTED),this.logger.info("Device disconnected successfully")}disconnect(e){return a(this,null,function*(){this.validateDeviceId(e),this.updateState(l.P.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield this.getApi().closeBLEConnection({deviceId:e}),this.finalizeDisconnect(e)}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.finalizeDisconnect(e)}})}write(e,t,i){return a(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.getServiceInfo(e);yield this.getWriteStrategy().execute(t,{deviceId:e,serviceId:n.serviceId,characteristicId:n.characteristicId},null!=i?i:{})})}discoverServices(e){return a(this,null,function*(){yield this.discoverAndCacheServices(e,()=>a(this,null,function*(){const t=yield this.getApi().getBLEDeviceServices({deviceId:e}),i=[];for(const n of t.services){const t=yield this.getApi().getBLEDeviceCharacteristics({deviceId:e,serviceId:n.uuid});i.push({serviceId:n.uuid,characteristics:t.characteristics.map(e=>({characteristicId:e.uuid,isWritable:!(!e.properties.write&&!e.properties.writeWithoutResponse)}))})}return i}))})}}class C extends f{getApi(){return Taro}}class D extends f{getApi(){return my}}class p extends f{getApi(){return swan}}class m extends f{getApi(){return tt}}class I extends f{getApi(){return qq}}const w=["000018f0-0000-1000-8000-00805f9b34fb","49535343-fe7d-4ae5-8fa9-9fafd205e455","e7810a71-73ae-499d-8c15-faa9aef0c3f2"];class E extends g{constructor(){super(...arguments),this.devices=new Map,this.discoveredDevices=new Map,this.connectionCleanupTimeout=null}static isSupported(){return"undefined"!=typeof navigator&&void 0!==navigator.bluetooth&&"function"==typeof navigator.bluetooth.requestDevice}requestDevice(e){return a(this,null,function*(){if(!E.isSupported())throw new l.B(l.n.PLATFORM_NOT_SUPPORTED,"Web Bluetooth API is not supported in this browser");this.logger.debug("Requesting Bluetooth device");try{const t=this.buildRequestOptions(e),i=yield navigator.bluetooth.requestDevice(t);return this.logger.info("Device selected:",i.name||i.id),i}catch(t){const e=l.o(t).message;if(e.includes("cancelled")||e.includes("canceled"))throw new l.B(l.n.CONNECTION_FAILED,"User cancelled device selection");if(e.includes("permission")||e.includes("denied"))throw new l.B(l.n.CONNECTION_FAILED,"Bluetooth permission denied");throw new l.B(l.n.CONNECTION_FAILED,"Failed to request Bluetooth device",l.o(t))}})}connect(e){return a(this,null,function*(){var t;if(this.validateDeviceId(e),this.devices.has(e)){const t=this.devices.get(e);if(null==t?void 0:t.server.connected)return this.logger.warn("Device already connected:",e),void this.updateState(l.P.CONNECTED);this.cleanupDeviceInfo(e)}this.updateState(l.P.CONNECTING),this.logger.debug("Connecting to device:",e);try{const n=yield this.getOrRequestDevice(e);if(!n.gatt)throw new l.B(l.n.CONNECTION_FAILED,"Device does not support GATT");const r=yield this.connectWithTimeout(n.gatt,1e4);this.logger.info("GATT server connected");const s=yield this.discoverWriteableCharacteristic(r);let c;try{const e=s.service.device;"readRemoteRssi"in e&&"function"==typeof e.readRemoteRssi&&(c=yield e.readRemoteRssi())}catch(i){this.logger.debug("RSSI reading not supported on this device")}const o={device:n,server:r,characteristic:s,discoveredAt:Date.now()};void 0!==c&&(o.rssiAtConnection=c),this.devices.set(e,o),this.serviceCache.set(e,{serviceId:(null==(t=s.service)?void 0:t.uuid)||"",characteristicId:s.uuid}),n.addEventListener("gattserverdisconnected",()=>{this.handleDisconnection(e)},{once:!0}),this.updateState(l.P.CONNECTED),this.logger.info("Device connected successfully")}catch(n){if(this.updateState(l.P.DISCONNECTED),this.logger.error("Connection failed:",n),n instanceof l.B)throw n;if(l.o(n).message.includes("timeout"))throw new l.B(l.n.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,l.o(n));throw new l.B(l.n.CONNECTION_FAILED,"Failed to connect to device "+e,l.o(n))}})}disconnect(e){return a(this,null,function*(){var t;yield Promise.resolve(),this.validateDeviceId(e);const i=this.devices.get(e);if(i){this.updateState(l.P.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null),(null==(t=null==i?void 0:i.server)?void 0:t.connected)&&(i.server.disconnect(),this.logger.debug("GATT server disconnected"))}catch(n){this.logger.warn("Disconnect error:",n)}finally{this.cleanupDeviceInfo(e),this.updateState(l.P.DISCONNECTED),this.logger.info("Device disconnected successfully")}}else this.logger.debug("Device not found in cache, nothing to disconnect")})}write(e,t,i){return a(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.devices.get(e);if(!n)throw new l.B(l.n.DEVICE_DISCONNECTED,"Device not connected. Call connect() first.");if(!n.server.connected)throw this.cleanupDeviceInfo(e),new l.B(l.n.DEVICE_DISCONNECTED,"Device disconnected");const r=this.validateOptions(i),{chunkSize:s,delay:c,retries:o}=r,a=new Uint8Array(t),u=Math.ceil(a.length/s);if(this.logger.debug(`Writing ${a.length} bytes in ${u} chunks`),0!==a.length){for(let t=0;t<a.length;t+=s){const i=a.slice(t,t+s),r=Math.floor(t/s)+1;let d=0;for(;o>=d;)try{if(!n.server.connected)throw this.cleanupDeviceInfo(e),new l.B(l.n.DEVICE_DISCONNECTED,"Device disconnected");yield n.characteristic.writeValueWithoutResponse(i.buffer),this.logger.debug(`Chunk ${r}/${u} written successfully`);break}catch(h){if(d++,d>o)throw this.logger.error(`Chunk ${r} failed after ${o} retries`),new l.B(l.n.WRITE_FAILED,`Failed to write chunk ${r}/${u}`,l.o(h));this.logger.warn(`Chunk ${r} write failed, retry ${d}/${o}`),yield new Promise(e=>setTimeout(e,c*d))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,c)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}getDeviceId(e){if(!e)throw new l.B(l.n.DEVICE_NOT_FOUND,"Device is required");return e.id||this.generateFallbackDeviceId(e)}getDeviceInfo(e){const t=this.devices.get(e);if(!t)return null;const i={deviceId:e,name:t.device.name||"Unknown Device",connected:t.server.connected};return void 0!==t.rssiAtConnection&&(i.rssi=t.rssiAtConnection),i}filterDevices(e,t){return e.filter(e=>{if(void 0!==t.minRSSI&&(void 0===e.rssi||e.rssi<t.minRSSI))return!1;if(void 0!==t.maxRSSI&&(void 0===e.rssi||e.rssi>t.maxRSSI))return!1;if(t.namePrefix&&!e.name.toLowerCase().startsWith(t.namePrefix.toLowerCase()))return!1;if(t.name){const i=t.name.toLowerCase();if(!e.name.toLowerCase().includes(i))return!1}if(t.serviceUUIDs&&t.serviceUUIDs.length>0){const i=e.device,n=Array.from(i.uuids||[]);if(!t.serviceUUIDs.some(e=>n.some(t=>t.toLowerCase()===e.toLowerCase())))return!1}return!0})}sortByRSSI(e,t=!1){return[...e].sort((e,i)=>{var n,r;const s=null!=(n=e.rssi)?n:-1/0,c=null!=(r=i.rssi)?r:-1/0;return t?s-c:c-s})}buildRequestOptions(e){var t,i;const n=[];if(null==e?void 0:e.acceptAllDevices)return{acceptAllDevices:!0,optionalServices:e.optionalServices||w};if((null==(t=null==e?void 0:e.serviceUUIDs)?void 0:t.length)&&n.push({services:e.serviceUUIDs}),(null==e?void 0:e.namePrefix)&&n.push({namePrefix:e.namePrefix}),(null==e?void 0:e.name)&&n.push({name:e.name}),null==(i=null==e?void 0:e.manufacturerDataFilter)?void 0:i.length)for(const r of e.manufacturerDataFilter){const e={manufacturerData:[{companyIdentifier:r.companyIdentifier}]};n.push(e)}return 0===n.length?{acceptAllDevices:!0,optionalServices:(null==e?void 0:e.optionalServices)||w}:{filters:n,optionalServices:(null==e?void 0:e.optionalServices)||w}}getOrRequestDevice(e){return a(this,null,function*(){const t=this.devices.get(e);if(null==t?void 0:t.device)return t.device;const i=this.discoveredDevices.get(e);return(null==i?void 0:i.device)?i.device:this.requestDevice()})}connectWithTimeout(e,t){return a(this,null,function*(){return new Promise((i,n)=>{const r=setTimeout(()=>{n(Error("Connection timeout"))},t);e.connect().then(e=>{clearTimeout(r),i(e)}).catch(e=>{clearTimeout(r),n(l.o(e))})})})}discoverWriteableCharacteristic(e){return a(this,null,function*(){this.logger.debug("Discovering services");try{const i=yield e.getPrimaryServices();for(const e of i)try{const t=yield e.getCharacteristics();for(const i of t)if(i.properties.write||i.properties.writeWithoutResponse)return this.logger.info("Found writeable characteristic:",{service:e.uuid,characteristic:i.uuid}),i}catch(t){this.logger.debug(`Failed to get characteristics for service ${e.uuid}:`,t)}throw new l.B(l.n.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof l.B)throw t;throw new l.B(l.n.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",l.o(t))}})}handleDisconnection(e){this.logger.warn("Device disconnected unexpectedly:",e),this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null),this.cleanupDeviceInfo(e),this.updateState(l.P.DISCONNECTED)}cleanupDeviceInfo(e){this.devices.delete(e),this.cleanupDevice(e)}generateFallbackDeviceId(e){return`fallback_${e.name||"unknown"}_${Date.now().toString(36)}`}destroy(){this.logger.debug("Destroying WebBluetoothAdapter"),this.connectionCleanupTimeout&&(clearTimeout(this.connectionCleanupTimeout),this.connectionCleanupTimeout=null);for(const[t,i]of this.devices)try{i.server.connected&&i.server.disconnect()}catch(e){this.logger.warn(`Error disconnecting device ${t}:`,e)}this.devices.clear(),this.discoveredDevices.clear(),super.destroy(),this.logger.info("WebBluetoothAdapter destroyed")}}const y=Object.freeze(Object.defineProperty({__proto__:null,WebBluetoothAdapter:E},Symbol.toStringTag,{value:"Module"}));exports.A=class{static create(){return this.createForPlatform(l.p())}static createForPlatform(e){switch(e){case l.q.WECHAT:return new C;case l.q.ALIPAY:return new D;case l.q.BAIDU:return new p;case l.q.BYTEDANCE:return new m;case l.q.QQ:return new I;case l.q.WEB:if(E.isSupported())return new E;throw new l.B(l.n.PLATFORM_NOT_SUPPORTED,"Web Bluetooth API is not supported in this browser. Please use a supported browser (Chrome, Edge, Opera).");default:throw new l.B(l.n.PLATFORM_NOT_SUPPORTED,`Platform ${e} is not supported. Please use a supported mini-program platform.`)}}},exports.B=g,exports.C=d,exports.D=u,exports.M=f,exports.Q=I,exports.T=C,exports.W=E,exports.a=D,exports.b=p,exports.c=m,exports.d=y;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const n=require("./shared-
|
|
1
|
+
"use strict";const n=require("./shared-CvHoYVGG.js");exports.E=class{constructor(e){var r,t,i;this.logger=n.L.scope("EscPos"),this.useEncodingService=null==(r=null==e?void 0:e.useEncodingService)||r,this.encodingService=new n.E({showWarnings:null==(t=null==e?void 0:e.showEncodingWarnings)||t,fallbackChar:null!=(i=null==e?void 0:e.fallbackChar)?i:"?"})}init(){return[new Uint8Array([27,64])]}encodeText(e,r){return this.useEncodingService&&this.encodingService.isSupported(r)?this.encodingService.encode(e,r):n.l.encode(e,r)}text(n,e="GBK"){return n&&"string"==typeof n?[this.encodeText(n,e)]:[]}feed(n=1){return[new Uint8Array([27,100,Math.max(1,Math.min(255,Math.floor(n)))])]}cut(){return[new Uint8Array([29,86,0])]}image(e,r,t){if(!(e&&e instanceof Uint8Array&&r>0&&t>0))return[];if(e.length!==r*t*4)return this.logger.warn(`Invalid image data length: expected ${r*t*4}, got ${e.length}`),[];const i=n.m.toBitmap(e,r,t),o=Math.ceil(r/8);return[new Uint8Array([29,118,48,0,o%256,Math.floor(o/256),t%256,Math.floor(t/256)]),i]}qr(n,e){var r,t,i,o;if(!n||"string"!=typeof n)return[];const a=null!=(r=null==e?void 0:e.model)?r:2,s=Math.max(1,Math.min(16,null!=(t=null==e?void 0:e.size)?t:6)),l=null!=(i=null==e?void 0:e.errorCorrection)?i:"M",u=[];u.push(new Uint8Array([29,40,107,4,0,49,65,1===a?49:50,0])),u.push(new Uint8Array([29,40,107,3,0,49,67,s]));const c=null!=(o={L:48,M:49,Q:50,H:51}[l])?o:49;u.push(new Uint8Array([29,40,107,3,0,49,69,c]));const h=this.encodeText(n,"GBK"),d=h.length+3,g=d%256,w=Math.floor(d/256);return u.push(new Uint8Array([29,40,107,g,w,49,80,48])),u.push(h),u.push(new Uint8Array([29,40,107,3,0,49,81,48])),u}openCashDrawer(n=0){return[new Uint8Array([27,112,n,50,200])]}beep(n=3,e=50){return[new Uint8Array([27,66,n,e])]}selfTest(){return[new Uint8Array([27,105])]}getStatus(){const n=[];for(let e=1;4>=e;e++)n.push(new Uint8Array([16,4,e]));return n}setCodePage(n){return[new Uint8Array([27,116,n])]}setLeftMargin(n){return[new Uint8Array([27,108,n])]}setPrintWidth(n){return[new Uint8Array([27,87,n])]}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{L as n,E as r,
|
|
1
|
+
import{L as n,E as r,l as e,m as t}from"./shared-C7eA759x.js";class i{constructor(e){var t,i,a;this.logger=n.scope("EscPos"),this.useEncodingService=null==(t=null==e?void 0:e.useEncodingService)||t,this.encodingService=new r({showWarnings:null==(i=null==e?void 0:e.showEncodingWarnings)||i,fallbackChar:null!=(a=null==e?void 0:e.fallbackChar)?a:"?"})}init(){return[new Uint8Array([27,64])]}encodeText(n,r){return this.useEncodingService&&this.encodingService.isSupported(r)?this.encodingService.encode(n,r):e.encode(n,r)}text(n,r="GBK"){return n&&"string"==typeof n?[this.encodeText(n,r)]:[]}feed(n=1){return[new Uint8Array([27,100,Math.max(1,Math.min(255,Math.floor(n)))])]}cut(){return[new Uint8Array([29,86,0])]}image(n,r,e){if(!(n&&n instanceof Uint8Array&&r>0&&e>0))return[];if(n.length!==r*e*4)return this.logger.warn(`Invalid image data length: expected ${r*e*4}, got ${n.length}`),[];const i=t.toBitmap(n,r,e),a=Math.ceil(r/8);return[new Uint8Array([29,118,48,0,a%256,Math.floor(a/256),e%256,Math.floor(e/256)]),i]}qr(n,r){var e,t,i,a;if(!n||"string"!=typeof n)return[];const o=null!=(e=null==r?void 0:r.model)?e:2,s=Math.max(1,Math.min(16,null!=(t=null==r?void 0:r.size)?t:6)),l=null!=(i=null==r?void 0:r.errorCorrection)?i:"M",u=[];u.push(new Uint8Array([29,40,107,4,0,49,65,1===o?49:50,0])),u.push(new Uint8Array([29,40,107,3,0,49,67,s]));const h=null!=(a={L:48,M:49,Q:50,H:51}[l])?a:49;u.push(new Uint8Array([29,40,107,3,0,49,69,h]));const c=this.encodeText(n,"GBK"),d=c.length+3,g=d%256,w=Math.floor(d/256);return u.push(new Uint8Array([29,40,107,g,w,49,80,48])),u.push(c),u.push(new Uint8Array([29,40,107,3,0,49,81,48])),u}openCashDrawer(n=0){return[new Uint8Array([27,112,n,50,200])]}beep(n=3,r=50){return[new Uint8Array([27,66,n,r])]}selfTest(){return[new Uint8Array([27,105])]}getStatus(){const n=[];for(let r=1;4>=r;r++)n.push(new Uint8Array([16,4,r]));return n}setCodePage(n){return[new Uint8Array([27,116,n])]}setLeftMargin(n){return[new Uint8Array([27,108,n])]}setPrintWidth(n){return[new Uint8Array([27,87,n])]}}export{i as E};
|