taro-bluetooth-print 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TaroBluePrint={})}(this,function(e){"use strict";var t=Object.defineProperty,i=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,n=Object.prototype.propertyIsEnumerable,s=(e,i,r)=>i in e?t(e,i,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[i]=r,o=(e,t)=>{for(var o in t||(t={}))r.call(t,o)&&s(e,o,t[o]);if(i)for(var o of i(t))n.call(t,o)&&s(e,o,t[o]);return e},c=(e,t,i)=>new Promise((r,n)=>{var s=e=>{try{c(i.next(e))}catch(t){n(t)}},o=e=>{try{c(i.throw(e))}catch(t){n(t)}},c=e=>e.done?r(e.value):Promise.resolve(e.value).then(s,o);c((i=i.apply(e,t)).next())}),a=(e=>(e.DISCONNECTED="disconnected",e.CONNECTING="connecting",e.CONNECTED="connected",e.DISCONNECTING="disconnecting",e.PRINTING="printing",e.PAUSED="paused",e))(a||{}),d=(e=>(e[e.DEBUG=0]="DEBUG",e[e.INFO=1]="INFO",e[e.WARN=2]="WARN",e[e.ERROR=3]="ERROR",e[e.NONE=4]="NONE",e))(d||{});const h=class e{static setLevel(e){this.level=e}static getLevel(){return this.level}static debug(e,...t){this.level}static info(e,...t){this.level}static warn(e,...t){this.level}static error(e,...t){this.level}static scope(t){this.prefix;return{debug:(t,...i)=>{e.level},info:(t,...i)=>{e.level},warn:(t,...i)=>{e.level},error:(t,...i)=>{e.level}}}};h.level=2,h.prefix="[TaroBTPrint]";let l=h;const u=l.scope("Encoding"),f=class{static encode(e,t="GBK"){if(!e||"string"!=typeof e)return new Uint8Array(0);const i=t.toUpperCase().replace("-","");return"UTF8"===i||"UTF-8"===i||this.warningShown||(u.warn(`Encoding ${t} not yet fully implemented, falling back to UTF-8. This may cause display issues with some printers.`),this.warningShown=!0),this.utf8Encoder.encode(e)}static isSupported(e){if(!e||"string"!=typeof e)return!1;const t=e.toUpperCase().replace("-","");return"UTF8"===t||"UTF-8"===t}};f.utf8Encoder=new TextEncoder,f.warningShown=!1;let g=f;class E{static toBitmap(e,t,i){if(!e||!(e instanceof Uint8Array)||t<=0||i<=0)return new Uint8Array(0);if(e.length!==t*i*4)throw new Error(`Invalid image data length: expected ${t*i*4}, got ${e.length}`);const r=Math.ceil(t/8),n=new Uint8Array(r*i),s=new Float32Array(t*i);for(let o=0;o<e.length;o+=4){const t=o/4,i=e[o]||0,r=e[o+1]||0,n=e[o+2]||0;s[t]=.299*i+.587*r+.114*n}for(let o=0;o<i;o++)for(let e=0;e<t;e++){const c=s[o*t+e]||0,a=c<128?0:255;if(0===a){const t=o*r+Math.floor(e/8),i=7-e%8;n[t]=(n[t]||0)|1<<i}const d=c-a;this.distributeError(s,t,i,e,o,d)}return n}static distributeError(e,t,i,r,n,s){const o=(o,c,a)=>{const d=r+o,h=n+c;if(d>=0&&d<t&&h>=0&&h<i){const i=h*t+d;e[i]=Math.max(0,Math.min(255,(e[i]||0)+s*a))}};o(1,0,7/16),o(-1,1,3/16),o(0,1,5/16),o(1,1,1/16)}}class v{constructor(){this.logger=l.scope("EscPos")}init(){return[new Uint8Array([27,64])]}text(e,t="GBK"){if(!e||"string"!=typeof e)return[];return[g.encode(e,t)]}feed(e=1){const t=Math.max(1,Math.min(255,Math.floor(e)));return[new Uint8Array([27,100,t])]}cut(){return[new Uint8Array([29,86,0])]}image(e,t,i){if(!e||!(e instanceof Uint8Array)||t<=0||i<=0)return[];if(e.length!==t*i*4)return this.logger.warn(`Invalid image data length: expected ${t*i*4}, got ${e.length}`),[];const r=E.toBitmap(e,t,i),n=Math.ceil(t/8),s=n%256,o=Math.floor(n/256),c=i%256,a=Math.floor(i/256);return[new Uint8Array([29,118,48,0,s,o,c,a]),r]}qr(e,t){var i,r,n,s;if(!e||"string"!=typeof e)return[];const o=null!=(i=null==t?void 0:t.model)?i:2,c=Math.max(1,Math.min(16,null!=(r=null==t?void 0:t.size)?r:6)),a=null!=(n=null==t?void 0:t.errorCorrection)?n:"M",d=[];d.push(new Uint8Array([29,40,107,4,0,49,65,1===o?49:50,0])),d.push(new Uint8Array([29,40,107,3,0,49,67,c]));const h=null!=(s={L:48,M:49,Q:50,H:51}[a])?s:49;d.push(new Uint8Array([29,40,107,3,0,49,69,h]));const l=g.encode(e,"GBK"),u=l.length+3,f=u%256,E=Math.floor(u/256);return d.push(new Uint8Array([29,40,107,f,E,49,80,48])),d.push(l),d.push(new Uint8Array([29,40,107,3,0,49,81,48])),d}}var C=(e=>(e.CONNECTION_FAILED="CONNECTION_FAILED",e.CONNECTION_TIMEOUT="CONNECTION_TIMEOUT",e.DEVICE_NOT_FOUND="DEVICE_NOT_FOUND",e.DEVICE_DISCONNECTED="DEVICE_DISCONNECTED",e.SERVICE_NOT_FOUND="SERVICE_NOT_FOUND",e.CHARACTERISTIC_NOT_FOUND="CHARACTERISTIC_NOT_FOUND",e.SERVICE_DISCOVERY_FAILED="SERVICE_DISCOVERY_FAILED",e.WRITE_FAILED="WRITE_FAILED",e.WRITE_TIMEOUT="WRITE_TIMEOUT",e.PRINT_JOB_IN_PROGRESS="PRINT_JOB_IN_PROGRESS",e.PRINT_JOB_CANCELLED="PRINT_JOB_CANCELLED",e.PRINT_JOB_FAILED="PRINT_JOB_FAILED",e.INVALID_CONFIGURATION="INVALID_CONFIGURATION",e.ENCODING_NOT_SUPPORTED="ENCODING_NOT_SUPPORTED",e.INVALID_IMAGE_DATA="INVALID_IMAGE_DATA",e.INVALID_QR_DATA="INVALID_QR_DATA",e.PLATFORM_NOT_SUPPORTED="PLATFORM_NOT_SUPPORTED",e))(C||{});class I extends Error{constructor(e,t,i){super(t),this.code=e,this.originalError=i,this.name="BluetoothPrintError",Error.captureStackTrace&&Error.captureStackTrace(this,I)}toString(){let e=`${this.name} [${this.code}]: ${this.message}`;return this.originalError&&(e+=`\nCaused by: ${this.originalError.message}`),e}}class D{constructor(){this.serviceCache=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 I(C.DEVICE_NOT_FOUND,"Invalid device ID provided")}validateBuffer(e){if(!(e&&e instanceof ArrayBuffer))throw new I(C.PRINT_JOB_FAILED,"Invalid buffer data provided")}validateOptions(e){var t,i,r;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!=(r=null==e?void 0:e.retries)?r:3))}}getServiceInfo(e){const t=this.serviceCache.get(e);if(!t)throw new I(C.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)}}class N extends D{connect(e){return c(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(a.CONNECTED);this.updateState(a.CONNECTING),this.logger.debug("Connecting to device:",e);try{const t=Taro.createBLEConnection({deviceId:e}),i=new Promise((e,t)=>{setTimeout(()=>{t(new Error("Connection timeout after 10 seconds"))},1e4)});yield Promise.race([t,i]),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(a.CONNECTED),this.logger.info("Device connected successfully"),Taro.onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(a.DISCONNECTED),this.cleanupDevice(e))})}catch(t){this.updateState(a.DISCONNECTED),this.logger.error("Connection failed:",t);const i=t.message||"";if(i.includes("timeout"))throw new I(C.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,t);if(i.includes("not found"))throw new I(C.DEVICE_NOT_FOUND,`Device ${e} not found`,t);throw new I(C.CONNECTION_FAILED,`Failed to connect to device ${e}`,t)}})}disconnect(e){return c(this,null,function*(){this.validateDeviceId(e),this.updateState(a.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield Taro.closeBLEConnection({deviceId:e}),this.cleanupDevice(e),this.updateState(a.DISCONNECTED),this.logger.info("Device disconnected successfully")}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.cleanupDevice(e),this.updateState(a.DISCONNECTED)}})}write(e,t,i){return c(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const r=this.getServiceInfo(e),n=this.validateOptions(i);try{if(!(yield Taro.getBLEConnectionState({deviceId:e})).connected)throw this.cleanupDevice(e),new I(C.DEVICE_DISCONNECTED,"Device disconnected")}catch(h){throw this.cleanupDevice(e),new I(C.DEVICE_DISCONNECTED,"Device disconnected",h)}const{chunkSize:s,delay:o,retries:c}=n,a=new Uint8Array(t),d=Math.ceil(a.length/s);if(this.logger.debug(`Writing ${a.length} bytes in ${d} chunks`),0!==a.length){for(let t=0;t<a.length;t+=s){const i=a.slice(t,t+s),n=Math.floor(t/s)+1;let l=0;for(;l<=c;)try{const t=Taro.writeBLECharacteristicValue({deviceId:e,serviceId:r.serviceId,characteristicId:r.characteristicId,value:i.buffer}),s=new Promise((e,t)=>{setTimeout(()=>{t(new Error("Write timeout after 5 seconds"))},5e3)});yield Promise.race([t,s]),this.logger.debug(`Chunk ${n}/${d} written successfully`);break}catch(h){if(l++,l>c)throw this.logger.error(`Chunk ${n} failed after ${c} retries`),new I(C.WRITE_FAILED,`Failed to write chunk ${n}/${d}`,h);this.logger.warn(`Chunk ${n} write failed, retry ${l}/${c}`),yield new Promise(e=>setTimeout(e,2*o))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,o)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}discoverServices(e){return c(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const t=yield Taro.getBLEDeviceServices({deviceId:e});for(const i of t.services){const t=(yield Taro.getBLEDeviceCharacteristics({deviceId:e,serviceId:i.uuid})).characteristics.find(e=>e.properties.write||e.properties.writeWithoutResponse);if(t)return this.serviceCache.set(e,{serviceId:i.uuid,characteristicId:t.uuid}),void this.logger.info("Found writeable characteristic:",{service:i.uuid,characteristic:t.uuid})}throw new I(C.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof I)throw t;throw new I(C.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",t)}})}}class w extends D{connect(e){return c(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(a.CONNECTED);this.updateState(a.CONNECTING),this.logger.debug("Connecting to device:",e);try{const t=my.createBLEConnection({deviceId:e}),i=new Promise((e,t)=>{setTimeout(()=>{t(new Error("Connection timeout after 10 seconds"))},1e4)});yield Promise.race([t,i]),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(a.CONNECTED),this.logger.info("Device connected successfully"),my.onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(a.DISCONNECTED),this.cleanupDevice(e))})}catch(t){this.updateState(a.DISCONNECTED),this.logger.error("Connection failed:",t);const i=t.message||"";if(i.includes("timeout"))throw new I(C.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,t);if(i.includes("not found"))throw new I(C.DEVICE_NOT_FOUND,`Device ${e} not found`,t);throw new I(C.CONNECTION_FAILED,`Failed to connect to device ${e}`,t)}})}disconnect(e){return c(this,null,function*(){this.validateDeviceId(e),this.updateState(a.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield my.closeBLEConnection({deviceId:e}),this.cleanupDevice(e),this.updateState(a.DISCONNECTED),this.logger.info("Device disconnected successfully")}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.cleanupDevice(e),this.updateState(a.DISCONNECTED)}})}write(e,t,i){return c(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const r=this.getServiceInfo(e),n=this.validateOptions(i);try{if(!(yield my.getBLEConnectionState({deviceId:e})).connected)throw this.cleanupDevice(e),new I(C.DEVICE_DISCONNECTED,"Device disconnected")}catch(h){throw this.cleanupDevice(e),new I(C.DEVICE_DISCONNECTED,"Device disconnected",h)}const{chunkSize:s,delay:o,retries:c}=n,a=new Uint8Array(t),d=Math.ceil(a.length/s);if(this.logger.debug(`Writing ${a.length} bytes in ${d} chunks`),0!==a.length){for(let t=0;t<a.length;t+=s){const i=a.slice(t,t+s),n=Math.floor(t/s)+1;let l=0;for(;l<=c;)try{const t=my.writeBLECharacteristicValue({deviceId:e,serviceId:r.serviceId,characteristicId:r.characteristicId,value:i.buffer}),s=new Promise((e,t)=>{setTimeout(()=>{t(new Error("Write timeout after 5 seconds"))},5e3)});yield Promise.race([t,s]),this.logger.debug(`Chunk ${n}/${d} written successfully`);break}catch(h){if(l++,l>c)throw this.logger.error(`Chunk ${n} failed after ${c} retries`),new I(C.WRITE_FAILED,`Failed to write chunk ${n}/${d}`,h);this.logger.warn(`Chunk ${n} write failed, retry ${l}/${c}`),yield new Promise(e=>setTimeout(e,2*o))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,o)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}discoverServices(e){return c(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const t=yield my.getBLEDeviceServices({deviceId:e});for(const i of t.services){const t=(yield my.getBLEDeviceCharacteristics({deviceId:e,serviceId:i.uuid})).characteristics.find(e=>e.properties.write||e.properties.writeWithoutResponse);if(t)return this.serviceCache.set(e,{serviceId:i.uuid,characteristicId:t.uuid}),void this.logger.info("Found writeable characteristic:",{service:i.uuid,characteristic:t.uuid})}throw new I(C.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof I)throw t;throw new I(C.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",t)}})}}class p extends D{connect(e){return c(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(a.CONNECTED);this.updateState(a.CONNECTING),this.logger.debug("Connecting to device:",e);try{const t=swan.createBLEConnection({deviceId:e}),i=new Promise((e,t)=>{setTimeout(()=>{t(new Error("Connection timeout after 10 seconds"))},1e4)});yield Promise.race([t,i]),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(a.CONNECTED),this.logger.info("Device connected successfully"),swan.onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(a.DISCONNECTED),this.cleanupDevice(e))})}catch(t){this.updateState(a.DISCONNECTED),this.logger.error("Connection failed:",t);const i=t.message||"";if(i.includes("timeout"))throw new I(C.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,t);if(i.includes("not found"))throw new I(C.DEVICE_NOT_FOUND,`Device ${e} not found`,t);throw new I(C.CONNECTION_FAILED,`Failed to connect to device ${e}`,t)}})}disconnect(e){return c(this,null,function*(){this.validateDeviceId(e),this.updateState(a.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield swan.closeBLEConnection({deviceId:e}),this.cleanupDevice(e),this.updateState(a.DISCONNECTED),this.logger.info("Device disconnected successfully")}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.cleanupDevice(e),this.updateState(a.DISCONNECTED)}})}write(e,t,i){return c(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const r=this.getServiceInfo(e),n=this.validateOptions(i);try{if(!(yield swan.getBLEConnectionState({deviceId:e})).connected)throw this.cleanupDevice(e),new I(C.DEVICE_DISCONNECTED,"Device disconnected")}catch(h){throw this.cleanupDevice(e),new I(C.DEVICE_DISCONNECTED,"Device disconnected",h)}const{chunkSize:s,delay:o,retries:c}=n,a=new Uint8Array(t),d=Math.ceil(a.length/s);if(this.logger.debug(`Writing ${a.length} bytes in ${d} chunks`),0!==a.length){for(let t=0;t<a.length;t+=s){const i=a.slice(t,t+s),n=Math.floor(t/s)+1;let l=0;for(;l<=c;)try{const t=swan.writeBLECharacteristicValue({deviceId:e,serviceId:r.serviceId,characteristicId:r.characteristicId,value:i.buffer}),s=new Promise((e,t)=>{setTimeout(()=>{t(new Error("Write timeout after 5 seconds"))},5e3)});yield Promise.race([t,s]),this.logger.debug(`Chunk ${n}/${d} written successfully`);break}catch(h){if(l++,l>c)throw this.logger.error(`Chunk ${n} failed after ${c} retries`),new I(C.WRITE_FAILED,`Failed to write chunk ${n}/${d}`,h);this.logger.warn(`Chunk ${n} write failed, retry ${l}/${c}`),yield new Promise(e=>setTimeout(e,2*o))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,o)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}discoverServices(e){return c(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const t=yield swan.getBLEDeviceServices({deviceId:e});for(const i of t.services){const t=(yield swan.getBLEDeviceCharacteristics({deviceId:e,serviceId:i.uuid})).characteristics.find(e=>e.properties.write||e.properties.writeWithoutResponse);if(t)return this.serviceCache.set(e,{serviceId:i.uuid,characteristicId:t.uuid}),void this.logger.info("Found writeable characteristic:",{service:i.uuid,characteristic:t.uuid})}throw new I(C.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof I)throw t;throw new I(C.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",t)}})}}class T extends D{connect(e){return c(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(a.CONNECTED);this.updateState(a.CONNECTING),this.logger.debug("Connecting to device:",e);try{const t=tt.createBLEConnection({deviceId:e}),i=new Promise((e,t)=>{setTimeout(()=>{t(new Error("Connection timeout after 10 seconds"))},1e4)});yield Promise.race([t,i]),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(a.CONNECTED),this.logger.info("Device connected successfully"),tt.onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(a.DISCONNECTED),this.cleanupDevice(e))})}catch(t){this.updateState(a.DISCONNECTED),this.logger.error("Connection failed:",t);const i=t.message||"";if(i.includes("timeout"))throw new I(C.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,t);if(i.includes("not found"))throw new I(C.DEVICE_NOT_FOUND,`Device ${e} not found`,t);throw new I(C.CONNECTION_FAILED,`Failed to connect to device ${e}`,t)}})}disconnect(e){return c(this,null,function*(){this.validateDeviceId(e),this.updateState(a.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield tt.closeBLEConnection({deviceId:e}),this.cleanupDevice(e),this.updateState(a.DISCONNECTED),this.logger.info("Device disconnected successfully")}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.cleanupDevice(e),this.updateState(a.DISCONNECTED)}})}write(e,t,i){return c(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const r=this.getServiceInfo(e),n=this.validateOptions(i);try{if(!(yield tt.getBLEConnectionState({deviceId:e})).connected)throw this.cleanupDevice(e),new I(C.DEVICE_DISCONNECTED,"Device disconnected")}catch(h){throw this.cleanupDevice(e),new I(C.DEVICE_DISCONNECTED,"Device disconnected",h)}const{chunkSize:s,delay:o,retries:c}=n,a=new Uint8Array(t),d=Math.ceil(a.length/s);if(this.logger.debug(`Writing ${a.length} bytes in ${d} chunks`),0!==a.length){for(let t=0;t<a.length;t+=s){const i=a.slice(t,t+s),n=Math.floor(t/s)+1;let l=0;for(;l<=c;)try{const t=tt.writeBLECharacteristicValue({deviceId:e,serviceId:r.serviceId,characteristicId:r.characteristicId,value:i.buffer}),s=new Promise((e,t)=>{setTimeout(()=>{t(new Error("Write timeout after 5 seconds"))},5e3)});yield Promise.race([t,s]),this.logger.debug(`Chunk ${n}/${d} written successfully`);break}catch(h){if(l++,l>c)throw this.logger.error(`Chunk ${n} failed after ${c} retries`),new I(C.WRITE_FAILED,`Failed to write chunk ${n}/${d}`,h);this.logger.warn(`Chunk ${n} write failed, retry ${l}/${c}`),yield new Promise(e=>setTimeout(e,2*o))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,o)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}discoverServices(e){return c(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const t=yield tt.getBLEDeviceServices({deviceId:e});for(const i of t.services){const t=(yield tt.getBLEDeviceCharacteristics({deviceId:e,serviceId:i.uuid})).characteristics.find(e=>e.properties.write||e.properties.writeWithoutResponse);if(t)return this.serviceCache.set(e,{serviceId:i.uuid,characteristicId:t.uuid}),void this.logger.info("Found writeable characteristic:",{service:i.uuid,characteristic:t.uuid})}throw new I(C.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof I)throw t;throw new I(C.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",t)}})}}var O=(e=>(e.WECHAT="wechat",e.ALIPAY="alipay",e.BAIDU="baidu",e.BYTEDANCE="bytedance",e.WEB="web",e.UNKNOWN="unknown",e))(O||{});class y{static create(){const e="undefined"!=typeof wx&&wx.request?"wechat":"undefined"!=typeof my&&my.request?"alipay":"undefined"!=typeof swan&&swan.request?"baidu":"undefined"!=typeof tt&&tt.request?"bytedance":"undefined"!=typeof window&&window.navigator?"web":"unknown";switch(e){case O.WECHAT:return new N;case O.ALIPAY:return new w;case O.BAIDU:return new p;case O.BYTEDANCE:return new T;default:throw new I(C.PLATFORM_NOT_SUPPORTED,`Platform ${e} is not supported. Please use a supported mini-program platform.`)}}static createForPlatform(e){switch(e){case O.WECHAT:return new N;case O.ALIPAY:return new w;case O.BAIDU:return new p;case O.BYTEDANCE:return new T;default:throw new I(C.PLATFORM_NOT_SUPPORTED,`Platform ${e} is not supported.`)}}}class S{constructor(){this.listeners=new Map}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>this.off(e,t)}once(e,t){const i=r=>{t(r),this.off(e,i)};return this.on(e,i)}off(e,t){const i=this.listeners.get(e);i&&(i.delete(t),0===i.size&&this.listeners.delete(e))}emit(e,t){const i=this.listeners.get(e);if(!i||0===i.size)return;new Set(i).forEach(e=>{try{e(void 0===t&&null===t?"":t)}catch(i){}})}removeAllListeners(e){e?this.listeners.delete(e):this.listeners.clear()}listenerCount(e){var t,i;return null!=(i=null==(t=this.listeners.get(e))?void 0:t.size)?i:0}hasListeners(e){return this.listenerCount(e)>0}}const m={adapter:{chunkSize:20,delay:20,retries:3,timeout:1e4},driver:{encoding:"GBK",paperWidth:58},logging:{level:d.WARN}};e.BluetoothPrintError=I,e.BluetoothPrinter=class extends S{constructor(e,t){var i,r;super(),this.deviceId=null,this.buffer=[],this.adapterOptions={},this.isPaused=!1,this.jobBuffer=null,this.jobOffset=0,this.logger=l.scope("BluetoothPrinter"),this.state=a.DISCONNECTED,this.adapter=e||y.create(),this.driver=t||new v,null==(r=(i=this.adapter).onStateChange)||r.call(i,e=>{this.state=e,this.emit("state-change",e),this.logger.debug("State changed:",e)})}connect(e){return c(this,null,function*(){this.logger.info("Connecting to device:",e);try{return this.deviceId=e,yield this.adapter.connect(e),this.buffer.push(...this.driver.init()),this.emit("connected",e),this.logger.info("Connected successfully"),this}catch(t){this.deviceId=null;const e=t instanceof I?t:new I(C.CONNECTION_FAILED,"Connection failed",t);throw this.emit("error",e),e}})}disconnect(){return c(this,null,function*(){if(!this.deviceId)return void this.logger.warn("Disconnect called but no device connected");const e=this.deviceId;this.logger.info("Disconnecting from device:",e);try{yield this.adapter.disconnect(e),this.deviceId=null,this.buffer=[],this.jobBuffer=null,this.jobOffset=0,this.emit("disconnected",e),this.logger.info("Disconnected successfully")}catch(t){const e=new I(C.DEVICE_DISCONNECTED,"Disconnect failed",t);throw this.emit("error",e),e}})}text(e,t){return this.logger.debug("Adding text:",e.substring(0,50)),this.buffer.push(...this.driver.text(e,t)),this}feed(e=1){return this.logger.debug("Adding feed:",e),this.buffer.push(...this.driver.feed(e)),this}cut(){return this.logger.debug("Adding cut command"),this.buffer.push(...this.driver.cut()),this}image(e,t,i){return this.logger.debug(`Adding image: ${t}x${i}`),this.buffer.push(...this.driver.image(e,t,i)),this}qr(e,t){return this.logger.debug("Adding QR code:",e.substring(0,50)),this.buffer.push(...this.driver.qr(e,t)),this}setOptions(e){return this.adapterOptions=o(o({},this.adapterOptions),e),this.logger.debug("Adapter options updated:",this.adapterOptions),this}pause(){this.isPaused=!0,this.state=a.PAUSED,this.emit("state-change",a.PAUSED),this.logger.info("Print job paused")}resume(){return c(this,null,function*(){if(this.isPaused&&this.jobBuffer){this.isPaused=!1,this.state=a.PRINTING,this.emit("state-change",a.PRINTING),this.logger.info("Print job resumed");try{yield this.processJob()}catch(e){const t=new I(C.PRINT_JOB_FAILED,"Failed to resume print job",e);throw this.emit("error",t),t}}else this.logger.warn("Resume called but job not paused or no job buffer")})}cancel(){this.isPaused=!1,this.jobBuffer=null,this.jobOffset=0,this.buffer=[],this.state=this.deviceId?a.CONNECTED:a.DISCONNECTED,this.emit("state-change",this.state),this.logger.info("Print job cancelled")}remaining(){return this.jobBuffer?this.jobBuffer.length-this.jobOffset:this.buffer.reduce((e,t)=>e+t.length,0)}print(){return c(this,null,function*(){if(!this.deviceId)throw new I(C.CONNECTION_FAILED,"Printer not connected. Call connect() first.");if(this.jobBuffer)throw new I(C.PRINT_JOB_IN_PROGRESS,"A print job is already in progress. Wait for completion or cancel it.");const e=this.buffer.reduce((e,t)=>e+t.length,0);this.logger.info(`Starting print job: ${e} bytes`);const t=new Uint8Array(e);let i=0;for(const n of this.buffer)t.set(n,i),i+=n.length;this.jobBuffer=t,this.jobOffset=0,this.buffer=[],this.isPaused=!1,this.state=a.PRINTING,this.emit("state-change",this.state);try{yield this.processJob(),this.isPaused?this.logger.info("Print job paused"):(this.emit("print-complete"),this.logger.info("Print job completed successfully"),this.state=a.CONNECTED,this.emit("state-change",this.state))}catch(r){const e=r instanceof I?r:new I(C.PRINT_JOB_FAILED,"Print job failed",r);throw this.emit("error",e),this.state=a.CONNECTED,this.emit("state-change",this.state),e}})}processJob(){return c(this,null,function*(){if(!this.jobBuffer||!this.deviceId)return;const e=this.jobBuffer.length,t=this.deviceId,i=this.jobBuffer;try{for(;this.jobOffset<i.length;){if(this.isPaused)return void this.logger.debug("Job paused at offset:",this.jobOffset);if(this.state!==a.CONNECTED&&this.state!==a.PRINTING&&this.state!==a.PAUSED)throw new I(C.DEVICE_DISCONNECTED,"Device disconnected during print job");const r=Math.min(this.jobOffset+512,i.length),n=i.slice(this.jobOffset,r);yield this.adapter.write(t,n.buffer,this.adapterOptions),this.jobOffset=r,this.hasListeners("progress")&&this.emit("progress",{sent:this.jobOffset,total:e})}}finally{this.jobOffset>=i.length&&(this.jobBuffer=null,this.jobOffset=0)}})}},e.DEFAULT_CONFIG=m,e.Encoding=g,e.ErrorCode=C,e.EscPos=v,e.EventEmitter=S,e.ImageProcessing=E,e.LogLevel=d,e.Logger=l,e.PrinterState=a,e.TaroAdapter=N,e.mergeConfig=function(e,t){return{adapter:o(o(o({},m.adapter),e.adapter),t.adapter),driver:o(o(o({},m.driver),e.driver),t.driver),logging:o(o(o({},m.logging),e.logging),t.logging)}},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TaroBluePrint={})}(this,function(e){"use strict";var t=Object.defineProperty,i=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable,s=(e,i,n)=>i in e?t(e,i,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[i]=n,o=(e,t)=>{for(var o in t||(t={}))n.call(t,o)&&s(e,o,t[o]);if(i)for(var o of i(t))r.call(t,o)&&s(e,o,t[o]);return e},c=(e,t,i)=>new Promise((n,r)=>{var s=e=>{try{c(i.next(e))}catch(t){r(t)}},o=e=>{try{c(i.throw(e))}catch(t){r(t)}},c=e=>e.done?n(e.value):Promise.resolve(e.value).then(s,o);c((i=i.apply(e,t)).next())}),a=(e=>(e.DISCONNECTED="disconnected",e.CONNECTING="connecting",e.CONNECTED="connected",e.DISCONNECTING="disconnecting",e.PRINTING="printing",e.PAUSED="paused",e))(a||{});class l{constructor(){this.listeners=new Map}on(e,t){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t),()=>this.off(e,t)}once(e,t){const i=n=>{t(n),this.off(e,i)};return this.on(e,i)}prepend(e,t){this.listeners.has(e)||this.listeners.set(e,new Set);const i=this.listeners.get(e),n=new Set;return n.add(t),i.forEach(e=>n.add(e)),this.listeners.set(e,n),()=>this.off(e,t)}prependOnce(e,t){const i=n=>{t(n),this.off(e,i)};return this.prepend(e,i)}off(e,t){const i=this.listeners.get(e);i&&(i.delete(t),0===i.size&&this.listeners.delete(e))}emit(e,t){const i=this.listeners.get(e);i&&0!==i.size&&new Set(i).forEach(e=>{try{null==t?e():e(t)}catch(i){}})}emitAsync(e,t){return c(this,null,function*(){const i=this.listeners.get(e);if(!i||0===i.size)return;const n=new Set(i),r=[];n.forEach(e=>{r.push(new Promise(i=>{try{null==t?e():e(t)}catch(n){}finally{i()}}))}),yield Promise.all(r)})}removeAllListeners(e){e?this.listeners.delete(e):this.listeners.clear()}listenerCount(e){var t,i;return null!=(i=null==(t=this.listeners.get(e))?void 0:t.size)?i:0}getListeners(e){const t=this.listeners.get(e);return t?Array.from(t):[]}eventNames(){return Array.from(this.listeners.keys())}hasListeners(e){return this.listenerCount(e)>0}}var h=(e=>(e[e.DEBUG=0]="DEBUG",e[e.INFO=1]="INFO",e[e.WARN=2]="WARN",e[e.ERROR=3]="ERROR",e[e.NONE=4]="NONE",e))(h||{});const d=class e{static configure(e){this.config=o(o({},this.config),e)}static setLevel(e){this.config.level=e}static getLevel(){return this.config.level}static formatPrefix(e,t){return`${t?`${this.config.prefix}:${t}`:this.config.prefix} [${{0:"DEBUG",1:"INFO",2:"WARN",3:"ERROR",4:"NONE"}[e]}]`}static formatMessage(e,t,i,n){return`${this.formatPrefix(e,n)} ${t}`}static log(e,t,i,n){if(this.config.level>e)return;this.formatPrefix(e,n);const r=this.formatMessage(e,t,i,n),s={level:e,message:t,args:i,timestamp:new Date,scope:n,formatted:r};this.config.handler&&this.config.handler(s)}static debug(e,...t){this.log(0,e,t)}static info(e,...t){this.log(1,e,t)}static warn(e,...t){this.log(2,e,t)}static error(e,...t){this.log(3,e,t)}static scope(t){return{debug:(i,...n)=>{e.log(0,i,n,t)},info:(i,...n)=>{e.log(1,i,n,t)},warn:(i,...n)=>{e.log(2,i,n,t)},error:(i,...n)=>{e.log(3,i,n,t)}}}};d.config={level:2,prefix:"[TaroBTPrint]"};let u=d;var f=(e=>(e.CONNECTION_FAILED="CONNECTION_FAILED",e.CONNECTION_TIMEOUT="CONNECTION_TIMEOUT",e.DEVICE_NOT_FOUND="DEVICE_NOT_FOUND",e.DEVICE_DISCONNECTED="DEVICE_DISCONNECTED",e.SERVICE_NOT_FOUND="SERVICE_NOT_FOUND",e.CHARACTERISTIC_NOT_FOUND="CHARACTERISTIC_NOT_FOUND",e.SERVICE_DISCOVERY_FAILED="SERVICE_DISCOVERY_FAILED",e.WRITE_FAILED="WRITE_FAILED",e.WRITE_TIMEOUT="WRITE_TIMEOUT",e.PRINT_JOB_IN_PROGRESS="PRINT_JOB_IN_PROGRESS",e.PRINT_JOB_CANCELLED="PRINT_JOB_CANCELLED",e.PRINT_JOB_FAILED="PRINT_JOB_FAILED",e.INVALID_CONFIGURATION="INVALID_CONFIGURATION",e.ENCODING_NOT_SUPPORTED="ENCODING_NOT_SUPPORTED",e.INVALID_IMAGE_DATA="INVALID_IMAGE_DATA",e.INVALID_QR_DATA="INVALID_QR_DATA",e.PLATFORM_NOT_SUPPORTED="PLATFORM_NOT_SUPPORTED",e))(f||{});class g extends Error{constructor(e,t,i){super(t),this.code=e,this.originalError=i,this.name="BluetoothPrintError",Error.captureStackTrace&&Error.captureStackTrace(this,g)}toString(){let e=`${this.name} [${this.code}]: ${this.message}`;return this.originalError&&(e+="\nCaused by: "+this.originalError.message),e}}var v=function(){return function(e){this.name=e}}(),p=function(){var e=function(t,i){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])})(t,i)};return function(t,i){function n(){this.constructor=t}e(t,i),t.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),E=function(e){function t(t){var i,n,r=e.call(this)||this;return r.name="ServiceNotFoundError",r.normalizedIdentifier="<UNKNOWN_IDENTIFIER>","string"==typeof t?r.normalizedIdentifier=t:t instanceof v?r.normalizedIdentifier="Token<"+(t.name||"UNSET_NAME")+">":t&&(t.name||(null===(i=t.prototype)||void 0===i?void 0:i.name))&&(r.normalizedIdentifier="MaybeConstructable<"+t.name+">"||"MaybeConstructable<"+(null===(n=t.prototype)||void 0===n?void 0:n.name)+">"),r}return p(t,e),Object.defineProperty(t.prototype,"message",{get:function(){return'Service with "'+this.normalizedIdentifier+'" identifier was not found in the container. Register it before usage via explicitly calling the "Container.set" function or using the "@Service()" decorator.'},enumerable:!1,configurable:!0}),t}(Error),I=function(){var e=function(t,i){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])})(t,i)};return function(t,i){function n(){this.constructor=t}e(t,i),t.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),y=function(e){function t(t){var i,n,r=e.call(this)||this;return r.name="CannotInstantiateValueError",r.normalizedIdentifier="<UNKNOWN_IDENTIFIER>","string"==typeof t?r.normalizedIdentifier=t:t instanceof v?r.normalizedIdentifier="Token<"+(t.name||"UNSET_NAME")+">":t&&(t.name||(null===(i=t.prototype)||void 0===i?void 0:i.name))&&(r.normalizedIdentifier="MaybeConstructable<"+t.name+">"||"MaybeConstructable<"+(null===(n=t.prototype)||void 0===n?void 0:n.name)+">"),r}return I(t,e),Object.defineProperty(t.prototype,"message",{get:function(){return'Cannot instantiate the requested value for the "'+this.normalizedIdentifier+"\" identifier. The related metadata doesn't contain a factory or a type to instantiate."},enumerable:!1,configurable:!0}),t}(Error),C=Symbol(),w=function(){return w=Object.assign||function(e){for(var t,i=1,n=arguments.length;n>i;i++)for(var r in t=arguments[i])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e},w.apply(this,arguments)},D=function(){function e(e){this.services=[],this.id=e}return e.prototype.has=function(e){return!!this.findService(e)},e.prototype.get=function(e){var t=N.of(void 0),i=t.findService(e),n=this.findService(e);if(i&&!0===i.global)return this.getServiceValue(i);if(n)return this.getServiceValue(n);if(i&&this!==t){var r=w({},i);r.value=C,this.set(r);var s=this.getServiceValue(r);return this.set(w(w({},r),{value:s})),s}if(i)return this.getServiceValue(i);throw new E(e)},e.prototype.getMany=function(e){var t=this;return this.findAllServices(e).map(function(e){return t.getServiceValue(e)})},e.prototype.set=function(e,t){var i=this;if(e instanceof Array)return e.forEach(function(e){return i.set(e)}),this;if("string"==typeof e||e instanceof v)return this.set({id:e,type:null,value:t,factory:void 0,global:!1,multiple:!1,eager:!1,transient:!1});if("function"==typeof e)return this.set({id:e,type:e,value:t,factory:void 0,global:!1,multiple:!1,eager:!1,transient:!1});var n=w({id:new v("UNREACHABLE"),type:null,factory:void 0,value:C,global:!1,multiple:!1,eager:!1,transient:!1},e),r=this.findService(n.id);return r&&!0!==r.multiple?Object.assign(r,n):this.services.push(n),n.eager&&this.get(n.id),this},e.prototype.remove=function(e){var t=this;return Array.isArray(e)?e.forEach(function(e){return t.remove(e)}):this.services=this.services.filter(function(i){return i.id!==e||(t.destroyServiceInstance(i),!1)}),this},e.prototype.reset=function(e){var t=this;switch(void 0===e&&(e={strategy:"resetValue"}),e.strategy){case"resetValue":this.services.forEach(function(e){return t.destroyServiceInstance(e)});break;case"resetServices":this.services.forEach(function(e){return t.destroyServiceInstance(e)}),this.services=[];break;default:throw Error("Received invalid reset strategy.")}return this},e.prototype.findAllServices=function(e){return this.services.filter(function(t){return t.id===e})},e.prototype.findService=function(e){return this.services.find(function(t){return t.id===e})},e.prototype.getServiceValue=function(e){var t,i=C;if(e.value!==C)return e.value;if(!e.factory&&!e.type)throw new y(e.id);if(e.factory)if(e.factory instanceof Array){var n=void 0;try{n=this.get(e.factory[0])}catch(c){if(!(c instanceof E))throw c;n=new e.factory[0]}i=n[e.factory[1]](this,e.id)}else i=e.factory(this,e.id);if(!e.factory&&e.type){var r=e.type,s=(null===(t=Reflect)||void 0===t?void 0:t.getMetadata("design:paramtypes",r))||[],o=this.initializeParams(r,s);o.push(this),i=new(r.bind.apply(r,function(){for(var e=0,t=0,i=arguments.length;i>t;t++)e+=arguments[t].length;var n=Array(e),r=0;for(t=0;i>t;t++)for(var s=arguments[t],o=0,c=s.length;c>o;o++,r++)n[r]=s[o];return n}([void 0],o)))}if(e.transient||i===C||(e.value=i),i===C)throw new y(e.id);return e.type&&this.applyPropertyHandlers(e.type,i),i},e.prototype.initializeParams=function(e,t){var i=this;return t.map(function(t,n){var r=N.handlers.find(function(t){return(t.object===e||t.object===Object.getPrototypeOf(e))&&t.index===n});return r?r.value(i):t&&t.name&&!i.isPrimitiveParamType(t.name)?i.get(t):void 0})},e.prototype.isPrimitiveParamType=function(e){return["string","boolean","number","object"].includes(e.toLowerCase())},e.prototype.applyPropertyHandlers=function(e,t){var i=this;N.handlers.forEach(function(n){"number"!=typeof n.index&&(n.object.constructor===e||e.prototype instanceof n.object.constructor)&&n.propertyName&&(t[n.propertyName]=n.value(i))})},e.prototype.destroyServiceInstance=function(e,t){if(void 0===t&&(t=!1),t||e.type||e.factory){if("function"==typeof(null==e?void 0:e.value).destroy)try{e.value.destroy()}catch(i){}e.value=C}},e}(),N=function(){function e(){}return e.of=function(e){if(void 0===e&&(e="default"),"default"===e)return this.globalInstance;var t=this.instances.find(function(t){return t.id===e});return t||(t=new D(e),this.instances.push(t)),t},e.has=function(e){return this.globalInstance.has(e)},e.get=function(e){return this.globalInstance.get(e)},e.getMany=function(e){return this.globalInstance.getMany(e)},e.set=function(e,t){return this.globalInstance.set(e,t),this},e.remove=function(e){return this.globalInstance.remove(e),this},e.reset=function(e){if(void 0===e&&(e="default"),"default"==e)this.globalInstance.reset(),this.instances.forEach(function(e){return e.reset()});else{var t=this.instances.find(function(t){return t.id===e});t&&(t.reset(),this.instances.splice(this.instances.indexOf(t),1))}return this},e.registerHandler=function(e){return this.handlers.push(e),this},e.import=function(e){return this},e.handlers=[],e.globalInstance=new D("default"),e.instances=[],e}();function m(e){return function(t){var i={id:t,type:t,factory:void 0,multiple:!1,global:!1,eager:!1,transient:!1,value:C};(e instanceof v||"string"==typeof e)&&(i.id=e),N.set(i)}}class b{constructor(){this.serviceCache=new Map,this.logger=u.scope("BaseAdapter")}onStateChange(e){this.stateCallback=e}updateState(e){this.stateCallback&&this.stateCallback(e)}validateDeviceId(e){if(!e||"string"!=typeof e)throw new g(f.DEVICE_NOT_FOUND,"Invalid device ID provided")}validateBuffer(e){if(!(e&&e instanceof ArrayBuffer))throw new g(f.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 g(f.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)}}class O extends b{connect(e){return c(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(a.CONNECTED);this.updateState(a.CONNECTING),this.logger.debug("Connecting to device:",e);try{let t;const i=Taro.createBLEConnection({deviceId:e}),n=new Promise((e,i)=>{t=setTimeout(()=>{i(Error("Connection timeout after 10 seconds"))},1e4)});yield Promise.race([i,n]),t&&clearTimeout(t),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(a.CONNECTED),this.logger.info("Device connected successfully"),Taro.onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(a.DISCONNECTED),this.cleanupDevice(e))})}catch(t){this.updateState(a.DISCONNECTED),this.logger.error("Connection failed:",t);const i=t.message||"";if(i.includes("timeout"))throw new g(f.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,t);if(i.includes("not found"))throw new g(f.DEVICE_NOT_FOUND,`Device ${e} not found`,t);throw new g(f.CONNECTION_FAILED,"Failed to connect to device "+e,t)}})}disconnect(e){return c(this,null,function*(){this.validateDeviceId(e),this.updateState(a.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield Taro.closeBLEConnection({deviceId:e}),this.cleanupDevice(e),this.updateState(a.DISCONNECTED),this.logger.info("Device disconnected successfully")}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.cleanupDevice(e),this.updateState(a.DISCONNECTED)}})}write(e,t,i){return c(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.getServiceInfo(e),r=this.validateOptions(i);try{if(!(yield Taro.getBLEConnectionState({deviceId:e})).connected)throw this.cleanupDevice(e),new g(f.DEVICE_DISCONNECTED,"Device disconnected")}catch(h){throw this.cleanupDevice(e),new g(f.DEVICE_DISCONNECTED,"Device disconnected",h)}const{chunkSize:s,delay:o,retries:c}=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 d=0;for(;c>=d;)try{const t=Taro.writeBLECharacteristicValue({deviceId:e,serviceId:n.serviceId,characteristicId:n.characteristicId,value:i.buffer}),s=new Promise((e,t)=>{setTimeout(()=>{t(Error("Write timeout after 5 seconds"))},5e3)});yield Promise.race([t,s]),this.logger.debug(`Chunk ${r}/${l} written successfully`);break}catch(h){if(d++,d>c)throw this.logger.error(`Chunk ${r} failed after ${c} retries`),new g(f.WRITE_FAILED,`Failed to write chunk ${r}/${l}`,h);this.logger.warn(`Chunk ${r} write failed, retry ${d}/${c}`),yield new Promise(e=>setTimeout(e,2*o))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,o)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}discoverServices(e){return c(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const t=yield Taro.getBLEDeviceServices({deviceId:e});for(const i of t.services){const t=(yield Taro.getBLEDeviceCharacteristics({deviceId:e,serviceId:i.uuid})).characteristics.find(e=>e.properties.write||e.properties.writeWithoutResponse);if(t)return this.serviceCache.set(e,{serviceId:i.uuid,characteristicId:t.uuid}),void this.logger.info("Found writeable characteristic:",{service:i.uuid,characteristic:t.uuid})}throw new g(f.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof g)throw t;throw new g(f.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",t)}})}}class T extends b{connect(e){return c(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(a.CONNECTED);this.updateState(a.CONNECTING),this.logger.debug("Connecting to device:",e);try{let t;const i=my.createBLEConnection({deviceId:e}),n=new Promise((e,i)=>{t=setTimeout(()=>{i(Error("Connection timeout after 10 seconds"))},1e4)});yield Promise.race([i,n]),t&&clearTimeout(t),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(a.CONNECTED),this.logger.info("Device connected successfully"),my.onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(a.DISCONNECTED),this.cleanupDevice(e))})}catch(t){this.updateState(a.DISCONNECTED),this.logger.error("Connection failed:",t);const i=t.message||"";if(i.includes("timeout"))throw new g(f.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,t);if(i.includes("not found"))throw new g(f.DEVICE_NOT_FOUND,`Device ${e} not found`,t);throw new g(f.CONNECTION_FAILED,"Failed to connect to device "+e,t)}})}disconnect(e){return c(this,null,function*(){this.validateDeviceId(e),this.updateState(a.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield my.closeBLEConnection({deviceId:e}),this.cleanupDevice(e),this.updateState(a.DISCONNECTED),this.logger.info("Device disconnected successfully")}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.cleanupDevice(e),this.updateState(a.DISCONNECTED)}})}write(e,t,i){return c(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.getServiceInfo(e),r=this.validateOptions(i);try{if(!(yield my.getBLEConnectionState({deviceId:e})).connected)throw this.cleanupDevice(e),new g(f.DEVICE_DISCONNECTED,"Device disconnected")}catch(h){throw this.cleanupDevice(e),new g(f.DEVICE_DISCONNECTED,"Device disconnected",h)}const{chunkSize:s,delay:o,retries:c}=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 d=0;for(;c>=d;)try{const t=my.writeBLECharacteristicValue({deviceId:e,serviceId:n.serviceId,characteristicId:n.characteristicId,value:i.buffer}),s=new Promise((e,t)=>{setTimeout(()=>{t(Error("Write timeout after 5 seconds"))},5e3)});yield Promise.race([t,s]),this.logger.debug(`Chunk ${r}/${l} written successfully`);break}catch(h){if(d++,d>c)throw this.logger.error(`Chunk ${r} failed after ${c} retries`),new g(f.WRITE_FAILED,`Failed to write chunk ${r}/${l}`,h);this.logger.warn(`Chunk ${r} write failed, retry ${d}/${c}`),yield new Promise(e=>setTimeout(e,2*o))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,o)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}discoverServices(e){return c(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const t=yield my.getBLEDeviceServices({deviceId:e});for(const i of t.services){const t=(yield my.getBLEDeviceCharacteristics({deviceId:e,serviceId:i.uuid})).characteristics.find(e=>e.properties.write||e.properties.writeWithoutResponse);if(t)return this.serviceCache.set(e,{serviceId:i.uuid,characteristicId:t.uuid}),void this.logger.info("Found writeable characteristic:",{service:i.uuid,characteristic:t.uuid})}throw new g(f.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof g)throw t;throw new g(f.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",t)}})}}class S extends b{connect(e){return c(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(a.CONNECTED);this.updateState(a.CONNECTING),this.logger.debug("Connecting to device:",e);try{let t;const i=swan.createBLEConnection({deviceId:e}),n=new Promise((e,i)=>{t=setTimeout(()=>{i(Error("Connection timeout after 10 seconds"))},1e4)});yield Promise.race([i,n]),t&&clearTimeout(t),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(a.CONNECTED),this.logger.info("Device connected successfully"),swan.onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(a.DISCONNECTED),this.cleanupDevice(e))})}catch(t){this.updateState(a.DISCONNECTED),this.logger.error("Connection failed:",t);const i=t.message||"";if(i.includes("timeout"))throw new g(f.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,t);if(i.includes("not found"))throw new g(f.DEVICE_NOT_FOUND,`Device ${e} not found`,t);throw new g(f.CONNECTION_FAILED,"Failed to connect to device "+e,t)}})}disconnect(e){return c(this,null,function*(){this.validateDeviceId(e),this.updateState(a.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield swan.closeBLEConnection({deviceId:e}),this.cleanupDevice(e),this.updateState(a.DISCONNECTED),this.logger.info("Device disconnected successfully")}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.cleanupDevice(e),this.updateState(a.DISCONNECTED)}})}write(e,t,i){return c(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.getServiceInfo(e),r=this.validateOptions(i);try{if(!(yield swan.getBLEConnectionState({deviceId:e})).connected)throw this.cleanupDevice(e),new g(f.DEVICE_DISCONNECTED,"Device disconnected")}catch(h){throw this.cleanupDevice(e),new g(f.DEVICE_DISCONNECTED,"Device disconnected",h)}const{chunkSize:s,delay:o,retries:c}=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 d=0;for(;c>=d;)try{const t=swan.writeBLECharacteristicValue({deviceId:e,serviceId:n.serviceId,characteristicId:n.characteristicId,value:i.buffer}),s=new Promise((e,t)=>{setTimeout(()=>{t(Error("Write timeout after 5 seconds"))},5e3)});yield Promise.race([t,s]),this.logger.debug(`Chunk ${r}/${l} written successfully`);break}catch(h){if(d++,d>c)throw this.logger.error(`Chunk ${r} failed after ${c} retries`),new g(f.WRITE_FAILED,`Failed to write chunk ${r}/${l}`,h);this.logger.warn(`Chunk ${r} write failed, retry ${d}/${c}`),yield new Promise(e=>setTimeout(e,2*o))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,o)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}discoverServices(e){return c(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const t=yield swan.getBLEDeviceServices({deviceId:e});for(const i of t.services){const t=(yield swan.getBLEDeviceCharacteristics({deviceId:e,serviceId:i.uuid})).characteristics.find(e=>e.properties.write||e.properties.writeWithoutResponse);if(t)return this.serviceCache.set(e,{serviceId:i.uuid,characteristicId:t.uuid}),void this.logger.info("Found writeable characteristic:",{service:i.uuid,characteristic:t.uuid})}throw new g(f.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof g)throw t;throw new g(f.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",t)}})}}class _ extends b{connect(e){return c(this,null,function*(){if(this.validateDeviceId(e),this.isDeviceConnected(e))return this.logger.warn("Device already connected:",e),void this.updateState(a.CONNECTED);this.updateState(a.CONNECTING),this.logger.debug("Connecting to device:",e);try{let t;const i=tt.createBLEConnection({deviceId:e}),n=new Promise((e,i)=>{t=setTimeout(()=>{i(Error("Connection timeout after 10 seconds"))},1e4)});yield Promise.race([i,n]),t&&clearTimeout(t),this.logger.info("BLE connection established"),yield this.discoverServices(e),this.updateState(a.CONNECTED),this.logger.info("Device connected successfully"),tt.onBLEConnectionStateChange(t=>{t.deviceId!==e||t.connected||(this.logger.warn("Device disconnected unexpectedly"),this.updateState(a.DISCONNECTED),this.cleanupDevice(e))})}catch(t){this.updateState(a.DISCONNECTED),this.logger.error("Connection failed:",t);const i=t.message||"";if(i.includes("timeout"))throw new g(f.CONNECTION_TIMEOUT,`Connection to device ${e} timed out`,t);if(i.includes("not found"))throw new g(f.DEVICE_NOT_FOUND,`Device ${e} not found`,t);throw new g(f.CONNECTION_FAILED,"Failed to connect to device "+e,t)}})}disconnect(e){return c(this,null,function*(){this.validateDeviceId(e),this.updateState(a.DISCONNECTING),this.logger.debug("Disconnecting from device:",e);try{yield tt.closeBLEConnection({deviceId:e}),this.cleanupDevice(e),this.updateState(a.DISCONNECTED),this.logger.info("Device disconnected successfully")}catch(t){this.logger.warn("Disconnect error (ignored):",t),this.cleanupDevice(e),this.updateState(a.DISCONNECTED)}})}write(e,t,i){return c(this,null,function*(){this.validateDeviceId(e),this.validateBuffer(t);const n=this.getServiceInfo(e),r=this.validateOptions(i);try{if(!(yield tt.getBLEConnectionState({deviceId:e})).connected)throw this.cleanupDevice(e),new g(f.DEVICE_DISCONNECTED,"Device disconnected")}catch(h){throw this.cleanupDevice(e),new g(f.DEVICE_DISCONNECTED,"Device disconnected",h)}const{chunkSize:s,delay:o,retries:c}=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 d=0;for(;c>=d;)try{const t=tt.writeBLECharacteristicValue({deviceId:e,serviceId:n.serviceId,characteristicId:n.characteristicId,value:i.buffer}),s=new Promise((e,t)=>{setTimeout(()=>{t(Error("Write timeout after 5 seconds"))},5e3)});yield Promise.race([t,s]),this.logger.debug(`Chunk ${r}/${l} written successfully`);break}catch(h){if(d++,d>c)throw this.logger.error(`Chunk ${r} failed after ${c} retries`),new g(f.WRITE_FAILED,`Failed to write chunk ${r}/${l}`,h);this.logger.warn(`Chunk ${r} write failed, retry ${d}/${c}`),yield new Promise(e=>setTimeout(e,2*o))}t+s<a.length&&(yield new Promise(e=>setTimeout(e,o)))}this.logger.info(`Successfully wrote ${a.length} bytes`)}else this.logger.warn("No data to write")})}discoverServices(e){return c(this,null,function*(){this.logger.debug("Discovering services for device:",e);try{const t=yield tt.getBLEDeviceServices({deviceId:e});for(const i of t.services){const t=(yield tt.getBLEDeviceCharacteristics({deviceId:e,serviceId:i.uuid})).characteristics.find(e=>e.properties.write||e.properties.writeWithoutResponse);if(t)return this.serviceCache.set(e,{serviceId:i.uuid,characteristicId:t.uuid}),void this.logger.info("Found writeable characteristic:",{service:i.uuid,characteristic:t.uuid})}throw new g(f.CHARACTERISTIC_NOT_FOUND,"No writeable characteristic found. Make sure the device is a supported printer.")}catch(t){if(t instanceof g)throw t;throw new g(f.SERVICE_DISCOVERY_FAILED,"Failed to discover device services",t)}})}}var P=(e=>(e.WECHAT="wechat",e.ALIPAY="alipay",e.BAIDU="baidu",e.BYTEDANCE="bytedance",e.WEB="web",e.UNKNOWN="unknown",e))(P||{});function A(e){return"object"==typeof e&&null!==e&&"request"in e}class B{static create(){const e="undefined"!=typeof wx&&A(wx)?"wechat":"undefined"!=typeof my&&A(my)?"alipay":"undefined"!=typeof swan&&A(swan)?"baidu":"undefined"!=typeof tt&&A(tt)?"bytedance":"undefined"!=typeof window&&"object"==typeof(t=window)&&null!==t&&"navigator"in t?"web":"unknown";var t;switch(e){case P.WECHAT:return new O;case P.ALIPAY:return new T;case P.BAIDU:return new S;case P.BYTEDANCE:return new _;default:throw new g(f.PLATFORM_NOT_SUPPORTED,`Platform ${e} is not supported. Please use a supported mini-program platform.`)}}static createForPlatform(e){switch(e){case P.WECHAT:return new O;case P.ALIPAY:return new T;case P.BAIDU:return new S;case P.BYTEDANCE:return new _;default:throw new g(f.PLATFORM_NOT_SUPPORTED,`Platform ${e} is not supported.`)}}}let M=class{constructor(e){var t,i;this.deviceId=null,this.state=a.DISCONNECTED,this.logger=u.scope("ConnectionManager"),this.adapter=e||B.create(),null==(i=(t=this.adapter).onStateChange)||i.call(t,e=>{this.state=e,this.logger.debug("State changed:",e)})}connect(e){return c(this,null,function*(){this.logger.info("Connecting to device:",e);try{this.deviceId=e,yield this.adapter.connect(e),this.state=a.CONNECTED,this.logger.info("Connected successfully")}catch(t){this.deviceId=null,this.state=a.DISCONNECTED;const e=t instanceof g?t:new g(f.CONNECTION_FAILED,"Connection failed",t);throw this.logger.error("Connection failed:",e),e}})}disconnect(){return c(this,null,function*(){if(!this.deviceId)return void this.logger.warn("Disconnect called but no device connected");const e=this.deviceId;this.logger.info("Disconnecting from device:",e);try{yield this.adapter.disconnect(e),this.deviceId=null,this.state=a.DISCONNECTED,this.logger.info("Disconnected successfully")}catch(t){const e=new g(f.DEVICE_DISCONNECTED,"Disconnect failed",t);throw this.logger.error("Disconnect failed:",e),e}})}isConnected(){return this.state===a.CONNECTED}getDeviceId(){return this.deviceId}getState(){return this.state}getAdapter(){return this.adapter}};M=((e,t)=>{for(var i,n=t,r=e.length-1;r>=0;r--)(i=e[r])&&(n=i(n)||n);return n})([m()],M);let R=class{constructor(e,t){if(this.jobBuffer=null,this.jobOffset=0,this._isPaused=!1,this._isInProgress=!1,this.adapterOptions={},this.logger=u.scope("PrintJobManager"),t)this.connectionManager=e,this.adapter=t;else if(e&&"function"==typeof e.connect)this.adapter=e,this.connectionManager={getDeviceId:()=>"test-device",isConnected:()=>!0,getState:()=>a.CONNECTED,connect:()=>Promise.resolve(),disconnect:()=>Promise.resolve(),getAdapter:()=>this.adapter};else{if(this.connectionManager=e,!this.connectionManager||"function"!=typeof this.connectionManager.getAdapter)throw Error("Printer adapter not provided and could not be retrieved from connection manager");this.adapter=this.connectionManager.getAdapter()}}start(e){return c(this,null,function*(){if(this._isInProgress)throw new g(f.PRINT_JOB_IN_PROGRESS,"A print job is already in progress. Wait for completion or cancel it.");this.logger.info(`Starting print job: ${e.length} bytes`),this.jobBuffer=e,this.jobOffset=0,this._isPaused=!1,this._isInProgress=!0;try{yield this.processJob(),this._isPaused?this.logger.info("Print job paused"):(this.logger.info("Print job completed successfully"),this._isInProgress=!1,this.jobBuffer=null,this.jobOffset=0)}catch(t){throw this.logger.error("Print job failed:",t),this._isInProgress=!1,this.jobBuffer=null,this.jobOffset=0,t instanceof g?t:new g(f.PRINT_JOB_FAILED,"Print job failed",t)}})}pause(){this._isInProgress?(this._isPaused=!0,this.logger.info("Print job paused")):this.logger.warn("Pause called but no print job in progress")}resume(){return c(this,null,function*(){if(this._isInProgress&&this._isPaused){this._isPaused=!1,this.logger.info("Print job resumed");try{yield this.processJob(),this._isPaused||(this.logger.info("Print job completed successfully"),this._isInProgress=!1,this.jobBuffer=null,this.jobOffset=0)}catch(e){throw this.logger.error("Print job failed after resume:",e),this._isInProgress=!1,this.jobBuffer=null,this.jobOffset=0,e instanceof g?e:new g(f.PRINT_JOB_FAILED,"Print job failed",e)}}else this.logger.warn("Resume called but no paused print job")})}cancel(){this._isInProgress?(this._isPaused=!1,this._isInProgress=!1,this.jobBuffer=null,this.jobOffset=0,this.logger.info("Print job cancelled")):this.logger.warn("Cancel called but no print job in progress")}remaining(){return this.jobBuffer?this.jobBuffer.length-this.jobOffset:0}isPaused(){return this._isPaused}isInProgress(){return this._isInProgress}setOptions(e){this.adapterOptions=o(o({},this.adapterOptions),e),this.logger.debug("Adapter options updated:",this.adapterOptions)}processJob(){return c(this,null,function*(){if(!this.jobBuffer)return;if(!this.adapter||"function"!=typeof this.adapter.write)throw new g(f.INVALID_CONFIGURATION,"Printer adapter does not support write operation");const e=this.jobBuffer.length,t=this.jobBuffer;try{for(;this.jobOffset<t.length;){if(this._isPaused)return void this.logger.debug("Job paused at offset:",this.jobOffset);const i=Math.min(this.jobOffset+512,t.length),n=t.slice(this.jobOffset,i);yield this.adapter.write(this.getDeviceId(),n.buffer,this.adapterOptions),this.jobOffset=i,this.logger.debug(`Processed ${this.jobOffset}/${e} bytes`)}}catch(i){throw this.logger.error("Error processing job:",i),i}})}getDeviceId(){const e=this.connectionManager.getDeviceId();if(!e)throw new g(f.DEVICE_DISCONNECTED,"Device ID not available");return e}};R=((e,t)=>{for(var i,n=t,r=e.length-1;r>=0;r--)(i=e[r])&&(n=i(n)||n);return n})([m()],R);const L=u.scope("Encoding"),F=class{static configure(e){this.config=o(o({},this.config),e)}static encode(e,t="GBK"){if(!e||"string"!=typeof e)return new Uint8Array(0);const i=t.toUpperCase().replace("-","");return"UTF8"===i||"UTF-8"===i||this.config.showWarnings&&!this.warningShown&&(L.warn(`Encoding ${t} not yet fully implemented, falling back to UTF-8. This may cause display issues with some printers.`),this.warningShown=!0),this.utf8Encoder.encode(e)}static isSupported(e){if(!e||"string"!=typeof e)return!1;const t=e.toUpperCase().replace("-","");return"UTF8"===t||"UTF-8"===t}};F.utf8Encoder=new TextEncoder,F.warningShown=!1,F.config={showWarnings:!0};let $=F;class j{static toBitmap(e,t,i){if(!(e&&e instanceof Uint8Array&&t>0&&i>0))return new Uint8Array(0);if(e.length!==t*i*4)throw Error(`Invalid image data length: expected ${t*i*4}, got ${e.length}`);const n=Math.ceil(t/8),r=new Uint8Array(n*i),s=new Float32Array(t*i);for(let o=0;o<e.length;o+=4){const t=o/4,i=e[o]||0,n=e[o+1]||0,r=e[o+2]||0;s[t]=.299*i+.587*n+.114*r}for(let o=0;i>o;o++)for(let e=0;t>e;e++){const c=s[o*t+e]||0,a=128>c?0:255;if(0===a){const t=o*n+Math.floor(e/8),i=7-e%8;r[t]=(r[t]||0)|1<<i}const l=c-a;this.distributeError(s,t,i,e,o,l)}return r}static distributeError(e,t,i,n,r,s){const o=(o,c,a)=>{const l=n+o,h=r+c;if(l>=0&&t>l&&h>=0&&i>h){const i=h*t+l;e[i]=Math.max(0,Math.min(255,(e[i]||0)+s*a))}};o(1,0,7/16),o(-1,1,3/16),o(0,1,5/16),o(1,1,1/16)}}class U{constructor(){this.logger=u.scope("EscPos")}init(){return[new Uint8Array([27,64])]}text(e,t="GBK"){return e&&"string"==typeof e?[$.encode(e,t)]:[]}feed(e=1){return[new Uint8Array([27,100,Math.max(1,Math.min(255,Math.floor(e)))])]}cut(){return[new Uint8Array([29,86,0])]}image(e,t,i){if(!(e&&e instanceof Uint8Array&&t>0&&i>0))return[];if(e.length!==t*i*4)return this.logger.warn(`Invalid image data length: expected ${t*i*4}, got ${e.length}`),[];const n=j.toBitmap(e,t,i),r=Math.ceil(t/8);return[new Uint8Array([29,118,48,0,r%256,Math.floor(r/256),i%256,Math.floor(i/256)]),n]}qr(e,t){var i,n,r,s;if(!e||"string"!=typeof e)return[];const o=null!=(i=null==t?void 0:t.model)?i:2,c=Math.max(1,Math.min(16,null!=(n=null==t?void 0:t.size)?n:6)),a=null!=(r=null==t?void 0:t.errorCorrection)?r:"M",l=[];l.push(new Uint8Array([29,40,107,4,0,49,65,1===o?49:50,0])),l.push(new Uint8Array([29,40,107,3,0,49,67,c]));const h=null!=(s={L:48,M:49,Q:50,H:51}[a])?s:49;l.push(new Uint8Array([29,40,107,3,0,49,69,h]));const d=$.encode(e,"GBK"),u=d.length+3,f=u%256,g=Math.floor(u/256);return l.push(new Uint8Array([29,40,107,f,g,49,80,48])),l.push(d),l.push(new Uint8Array([29,40,107,3,0,49,81,48])),l}}let V=class{constructor(e){this.buffer=[],this.logger=u.scope("CommandBuilder"),this.driver=e||new U,this.buffer.push(...this.driver.init())}text(e,t){return this.logger.debug("Adding text:",e.substring(0,50)),this.buffer.push(...this.driver.text(e,t)),this}feed(e=1){return this.logger.debug("Adding feed:",e),this.buffer.push(...this.driver.feed(e)),this}cut(){return this.logger.debug("Adding cut command"),this.buffer.push(...this.driver.cut()),this}image(e,t,i){return this.logger.debug(`Adding image: ${t}x${i}`),this.buffer.push(...this.driver.image(e,t,i)),this}qr(e,t){return this.logger.debug("Adding QR code:",e.substring(0,50)),this.buffer.push(...this.driver.qr(e,t)),this}clear(){return this.logger.debug("Clearing buffer"),this.buffer=[],this.buffer.push(...this.driver.init()),this}getBuffer(){const e=this.buffer.reduce((e,t)=>e+t.length,0),t=new Uint8Array(e);let i=0;for(const n of this.buffer)t.set(n,i),i+=n.length;return t}getTotalBytes(){return this.buffer.reduce((e,t)=>e+t.length,0)}};V=((e,t)=>{for(var i,n=t,r=e.length-1;r>=0;r--)(i=e[r])&&(n=i(n)||n);return n})([m()],V);e.BluetoothPrinter=class extends l{constructor(e,t,i){if(super(),this.logger=u.scope("BluetoothPrinter"),this.state=a.DISCONNECTED,e&&"function"==typeof e.connect){const i=e,n=t;this.connectionManager=new M(i),this.printJobManager=new R(this.connectionManager,i),this.commandBuilder=new V(n)}else this.connectionManager=e,this.printJobManager=t,this.commandBuilder=i,this.connectionManager||(this.connectionManager=new M,this.printJobManager=new R(this.connectionManager),this.commandBuilder=new V);this.updateState()}updateState(){let e;e=this.connectionManager&&"function"==typeof this.connectionManager.getState?this.connectionManager.getState():a.CONNECTED;let t=!1,i=!1;this.printJobManager&&(t="function"==typeof this.printJobManager.isInProgress&&this.printJobManager.isInProgress(),i="function"==typeof this.printJobManager.isPaused&&this.printJobManager.isPaused()),this.state=i?a.PAUSED:t?a.PRINTING:e,this.emit("state-change",this.state),this.logger.debug("State updated:",this.state)}connect(e){return c(this,null,function*(){this.logger.info("Connecting to device:",e);try{return yield this.connectionManager.connect(e),this.updateState(),this.emit("connected",e),this.logger.info("Connected successfully"),this}catch(t){const e=t instanceof g?t:new g(f.CONNECTION_FAILED,"Connection failed",t);throw this.emit("error",e),this.updateState(),e}})}disconnect(){return c(this,null,function*(){const e=this.connectionManager.getDeviceId();if(e){this.logger.info("Disconnecting from device:",e);try{yield this.connectionManager.disconnect(),this.printJobManager.cancel(),this.updateState(),this.emit("disconnected",e),this.logger.info("Disconnected successfully")}catch(t){const e=new g(f.DEVICE_DISCONNECTED,"Disconnect failed",t);throw this.emit("error",e),this.updateState(),e}}else this.logger.warn("Disconnect called but no device connected")})}text(e,t){return this.commandBuilder.text(e,t),this}feed(e=1){return this.commandBuilder.feed(e),this}cut(){return this.commandBuilder.cut(),this}image(e,t,i){return this.commandBuilder.image(e,t,i),this}qr(e,t){return this.commandBuilder.qr(e,t),this}setOptions(e){return this.printJobManager.setOptions(e),this}pause(){this.printJobManager.pause(),this.updateState(),this.logger.info("Print job paused")}resume(){return c(this,null,function*(){this.logger.info("Resuming print job");try{yield this.printJobManager.resume(),this.updateState(),this.logger.info("Print job resumed")}catch(e){const t=new g(f.PRINT_JOB_FAILED,"Failed to resume print job",e);throw this.emit("error",t),this.updateState(),t}})}cancel(){this.printJobManager.cancel(),this.commandBuilder.clear(),this.updateState(),this.logger.info("Print job cancelled")}remaining(){return this.printJobManager.remaining()}print(){return c(this,null,function*(){if(!this.connectionManager.isConnected())throw new g(f.CONNECTION_FAILED,"Printer not connected. Call connect() first.");const e=this.commandBuilder.getBuffer();this.logger.info(`Starting print job: ${e.length} bytes`),this.commandBuilder.clear(),this.updateState();try{yield this.printJobManager.start(e),"function"==typeof this.printJobManager.isPaused&&this.printJobManager.isPaused()?this.logger.info("Print job paused"):(this.emit("print-complete"),this.logger.info("Print job completed successfully"))}catch(t){this.logger.error("Print job failed with error:",t);const e=t instanceof g?t:new g(f.PRINT_JOB_FAILED,"Print job failed",t);throw this.emit("error",e),e}finally{this.updateState()}})}},e.BluetoothPrinter=((e,t)=>{for(var i,n=t,r=e.length-1;r>=0;r--)(i=e[r])&&(n=i(n)||n);return n})([m()],e.BluetoothPrinter);const k={adapter:{chunkSize:20,delay:20,retries:3,timeout:1e4},driver:{encoding:"GBK",paperWidth:58},logging:{level:h.WARN}};e.BluetoothPrintError=g,e.DEFAULT_CONFIG=k,e.Encoding=$,e.ErrorCode=f,e.EscPos=U,e.EventEmitter=l,e.ImageProcessing=j,e.LogLevel=h,e.Logger=u,e.PrinterState=a,e.TaroAdapter=O,e.mergeConfig=function(e,t){return{adapter:o(o(o({},k.adapter),e.adapter),t.adapter),driver:o(o(o({},k.driver),e.driver),t.driver),logging:o(o(o({},k.logging),e.logging),t.logging)}},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
@@ -14,10 +14,10 @@ export declare abstract class BaseAdapter implements IPrinterAdapter {
14
14
  protected stateCallback?: (state: PrinterState) => void;
15
15
  protected serviceCache: Map<string, ServiceInfo>;
16
16
  protected readonly logger: {
17
- debug: (message: string, ...args: any[]) => void;
18
- info: (message: string, ...args: any[]) => void;
19
- warn: (message: string, ...args: any[]) => void;
20
- error: (message: string, ...args: any[]) => void;
17
+ debug: (message: string, ...args: unknown[]) => void;
18
+ info: (message: string, ...args: unknown[]) => void;
19
+ warn: (message: string, ...args: unknown[]) => void;
20
+ error: (message: string, ...args: unknown[]) => void;
21
21
  };
22
22
  /**
23
23
  * Connect to a Bluetooth device
@@ -1,6 +1,7 @@
1
- import { IPrinterAdapter, IPrinterDriver, IAdapterOptions, IQrOptions, PrinterState } from '../types';
1
+ import { IAdapterOptions, IQrOptions, PrinterState, IPrinterAdapter, IPrinterDriver } from '../types';
2
2
  import { EventEmitter } from '../EventEmitter';
3
3
  import { BluetoothPrintError } from '../errors/BluetoothError';
4
+ import { IConnectionManager, IPrintJobManager, ICommandBuilder } from '../services/interfaces';
4
5
 
5
6
  /**
6
7
  * Event types emitted by BluetoothPrinter
@@ -50,24 +51,27 @@ export interface PrinterEvents {
50
51
  * ```
51
52
  */
52
53
  export declare class BluetoothPrinter extends EventEmitter<PrinterEvents> {
53
- private adapter;
54
- private driver;
55
- private deviceId;
56
- private buffer;
57
- private adapterOptions;
58
- private isPaused;
59
- private jobBuffer;
60
- private jobOffset;
61
54
  private readonly logger;
62
55
  /** Current printer state */
63
56
  state: PrinterState;
57
+ /** Connection manager instance */
58
+ private connectionManager;
59
+ /** Print job manager instance */
60
+ private printJobManager;
61
+ /** Command builder instance */
62
+ private commandBuilder;
64
63
  /**
65
64
  * Creates a new BluetoothPrinter instance
66
65
  *
67
- * @param adapter - Custom adapter implementation (defaults to platform-specific adapter)
68
- * @param driver - Custom driver implementation (defaults to EscPos)
66
+ * @param connectionManagerOrAdapter - Connection manager instance or printer adapter instance (for backward compatibility)
67
+ * @param printJobManagerOrDriver - Print job manager instance or printer driver instance (for backward compatibility)
68
+ * @param commandBuilder - Command builder instance (optional)
69
69
  */
70
- constructor(adapter?: IPrinterAdapter, driver?: IPrinterDriver);
70
+ constructor(connectionManagerOrAdapter?: IConnectionManager | IPrinterAdapter, printJobManagerOrDriver?: IPrintJobManager | IPrinterDriver, commandBuilder?: ICommandBuilder);
71
+ /**
72
+ * Updates the current state based on the connection manager and print job manager states
73
+ */
74
+ private updateState;
71
75
  /**
72
76
  * Connects to a Bluetooth device
73
77
  *
@@ -226,9 +230,4 @@ export declare class BluetoothPrinter extends EventEmitter<PrinterEvents> {
226
230
  * ```
227
231
  */
228
232
  print(): Promise<void>;
229
- /**
230
- * Processes the print job in chunks
231
- * Supports pause/resume and emits progress events
232
- */
233
- private processJob;
234
233
  }
@@ -24,7 +24,7 @@
24
24
  * });
25
25
  * ```
26
26
  */
27
- export declare class EventEmitter<T extends Record<string, any>> {
27
+ export declare class EventEmitter<T> {
28
28
  private listeners;
29
29
  /**
30
30
  * Subscribe to an event
@@ -42,6 +42,22 @@ export declare class EventEmitter<T extends Record<string, any>> {
42
42
  * @returns Unsubscribe function
43
43
  */
44
44
  once<K extends keyof T>(event: K, handler: (data: T[K]) => void): () => void;
45
+ /**
46
+ * Adds a listener to the beginning of the listeners array for the specified event
47
+ *
48
+ * @param event - Event name
49
+ * @param handler - Event handler function
50
+ * @returns Unsubscribe function
51
+ */
52
+ prepend<K extends keyof T>(event: K, handler: (data: T[K]) => void): () => void;
53
+ /**
54
+ * Adds a one-time listener to the beginning of the listeners array for the specified event
55
+ *
56
+ * @param event - Event name
57
+ * @param handler - Event handler function
58
+ * @returns Unsubscribe function
59
+ */
60
+ prependOnce<K extends keyof T>(event: K, handler: (data: T[K]) => void): () => void;
45
61
  /**
46
62
  * Unsubscribe from an event
47
63
  *
@@ -56,6 +72,14 @@ export declare class EventEmitter<T extends Record<string, any>> {
56
72
  * @param data - Event payload (optional for void events)
57
73
  */
58
74
  protected emit<K extends keyof T>(event: K, data?: T[K]): void;
75
+ /**
76
+ * Asynchronously emit an event to all subscribers, waiting for all handlers to complete
77
+ *
78
+ * @param event - Event name
79
+ * @param data - Event payload (optional for void events)
80
+ * @returns Promise that resolves when all handlers have completed
81
+ */
82
+ protected emitAsync<K extends keyof T>(event: K, data?: T[K]): Promise<void>;
59
83
  /**
60
84
  * Remove all event listeners
61
85
  * @param event - Optional event name to remove all listeners for a specific event
@@ -68,6 +92,19 @@ export declare class EventEmitter<T extends Record<string, any>> {
68
92
  * @returns Number of listeners
69
93
  */
70
94
  listenerCount<K extends keyof T>(event: K): number;
95
+ /**
96
+ * Get all listeners for an event
97
+ *
98
+ * @param event - Event name
99
+ * @returns Array of event handlers
100
+ */
101
+ getListeners<K extends keyof T>(event: K): Array<(data: T[K]) => void>;
102
+ /**
103
+ * Get all event names that have listeners
104
+ *
105
+ * @returns Array of event names
106
+ */
107
+ eventNames(): Array<keyof T>;
71
108
  /**
72
109
  * Check if there are any listeners for an event
73
110
  *
@@ -0,0 +1,73 @@
1
+ import { IPrinterDriver, IQrOptions } from '../types';
2
+ import { ICommandBuilder } from '../interfaces';
3
+
4
+ /**
5
+ * Command Builder implementation
6
+ */
7
+ export declare class CommandBuilder implements ICommandBuilder {
8
+ private driver;
9
+ private buffer;
10
+ private readonly logger;
11
+ /**
12
+ * Creates a new CommandBuilder instance
13
+ *
14
+ * @param driver - Printer driver instance
15
+ */
16
+ constructor(driver?: IPrinterDriver);
17
+ /**
18
+ * Adds text to the print queue
19
+ *
20
+ * @param content - Text content
21
+ * @param encoding - Text encoding
22
+ * @returns this - For method chaining
23
+ */
24
+ text(content: string, encoding?: string): this;
25
+ /**
26
+ * Adds line feeds to the print queue
27
+ *
28
+ * @param lines - Number of lines to feed
29
+ * @returns this - For method chaining
30
+ */
31
+ feed(lines?: number): this;
32
+ /**
33
+ * Adds a paper cut command to the print queue
34
+ *
35
+ * @returns this - For method chaining
36
+ */
37
+ cut(): this;
38
+ /**
39
+ * Adds an image to the print queue
40
+ *
41
+ * @param data - Image data as Uint8Array
42
+ * @param width - Image width
43
+ * @param height - Image height
44
+ * @returns this - For method chaining
45
+ */
46
+ image(data: Uint8Array, width: number, height: number): this;
47
+ /**
48
+ * Adds a QR code to the print queue
49
+ *
50
+ * @param content - QR code content
51
+ * @param options - QR code options
52
+ * @returns this - For method chaining
53
+ */
54
+ qr(content: string, options?: IQrOptions): this;
55
+ /**
56
+ * Clears the print queue
57
+ *
58
+ * @returns this - For method chaining
59
+ */
60
+ clear(): this;
61
+ /**
62
+ * Gets the current buffer
63
+ *
64
+ * @returns Uint8Array - Current print buffer
65
+ */
66
+ getBuffer(): Uint8Array;
67
+ /**
68
+ * Gets the total number of bytes in the buffer
69
+ *
70
+ * @returns number - Total bytes
71
+ */
72
+ getTotalBytes(): number;
73
+ }
@@ -0,0 +1,53 @@
1
+ import { IPrinterAdapter, PrinterState } from '../types';
2
+ import { IConnectionManager } from '../interfaces';
3
+
4
+ /**
5
+ * Connection Manager implementation
6
+ */
7
+ export declare class ConnectionManager implements IConnectionManager {
8
+ private adapter;
9
+ private deviceId;
10
+ private state;
11
+ private readonly logger;
12
+ /**
13
+ * Creates a new ConnectionManager instance
14
+ */
15
+ constructor(adapter?: IPrinterAdapter);
16
+ /**
17
+ * Connects to a Bluetooth device
18
+ *
19
+ * @param deviceId - Bluetooth device ID
20
+ * @returns Promise<void>
21
+ */
22
+ connect(deviceId: string): Promise<void>;
23
+ /**
24
+ * Disconnects from the current device
25
+ *
26
+ * @returns Promise<void>
27
+ */
28
+ disconnect(): Promise<void>;
29
+ /**
30
+ * Checks if a device is connected
31
+ *
32
+ * @returns boolean - True if connected, false otherwise
33
+ */
34
+ isConnected(): boolean;
35
+ /**
36
+ * Gets the current device ID
37
+ *
38
+ * @returns string | null - Device ID or null if not connected
39
+ */
40
+ getDeviceId(): string | null;
41
+ /**
42
+ * Gets the current connection state
43
+ *
44
+ * @returns PrinterState - Current state
45
+ */
46
+ getState(): PrinterState;
47
+ /**
48
+ * Gets the printer adapter instance
49
+ *
50
+ * @returns IPrinterAdapter - Printer adapter
51
+ */
52
+ getAdapter(): IPrinterAdapter;
53
+ }
@@ -0,0 +1,82 @@
1
+ import { IPrinterAdapter, IAdapterOptions } from '../types';
2
+ import { IPrintJobManager, IConnectionManager } from '../interfaces';
3
+
4
+ /**
5
+ * Print Job Manager implementation
6
+ */
7
+ export declare class PrintJobManager implements IPrintJobManager {
8
+ private adapter;
9
+ private connectionManager;
10
+ private jobBuffer;
11
+ private jobOffset;
12
+ private _isPaused;
13
+ private _isInProgress;
14
+ private adapterOptions;
15
+ private readonly logger;
16
+ /**
17
+ * Creates a new PrintJobManager instance
18
+ *
19
+ * @param connectionManagerOrAdapter - Connection manager instance or adapter instance (for backward compatibility)
20
+ * @param adapter - Printer adapter instance (optional, will be taken from connectionManager if not provided)
21
+ */
22
+ constructor(connectionManagerOrAdapter?: IConnectionManager | IPrinterAdapter, adapter?: IPrinterAdapter);
23
+ /**
24
+ * Starts a print job
25
+ *
26
+ * @param buffer - Print data buffer
27
+ * @returns Promise<void>
28
+ */
29
+ start(buffer: Uint8Array): Promise<void>;
30
+ /**
31
+ * Pauses the current print job
32
+ */
33
+ pause(): void;
34
+ /**
35
+ * Resumes a paused print job
36
+ *
37
+ * @returns Promise<void>
38
+ */
39
+ resume(): Promise<void>;
40
+ /**
41
+ * Cancels the current print job
42
+ */
43
+ cancel(): void;
44
+ /**
45
+ * Gets the number of bytes remaining to print
46
+ *
47
+ * @returns number - Bytes remaining
48
+ */
49
+ remaining(): number;
50
+ /**
51
+ * Checks if the print job is paused
52
+ *
53
+ * @returns boolean - True if paused, false otherwise
54
+ */
55
+ isPaused(): boolean;
56
+ /**
57
+ * Checks if a print job is in progress
58
+ *
59
+ * @returns boolean - True if in progress, false otherwise
60
+ */
61
+ isInProgress(): boolean;
62
+ /**
63
+ * Sets adapter options for write operations
64
+ *
65
+ * @param options - Adapter options
66
+ */
67
+ setOptions(options: IAdapterOptions): void;
68
+ /**
69
+ * Processes the print job in chunks
70
+ * Supports pause/resume functionality
71
+ *
72
+ * @returns Promise<void>
73
+ */
74
+ private processJob;
75
+ /**
76
+ * Gets the current device ID from the connection manager
77
+ *
78
+ * @returns string - Device ID
79
+ * @throws BluetoothPrintError if no device is connected
80
+ */
81
+ private getDeviceId;
82
+ }