@opendisplay/opendisplay 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -651,7 +651,10 @@ declare class OpenDisplayDevice {
651
651
  * await device.uploadImage(imageData, {
652
652
  * refreshMode: RefreshMode.FULL,
653
653
  * ditherMode: DitherMode.BURKES,
654
- * compress: true
654
+ * compress: true,
655
+ * onProgress: (current, total, stage) => {
656
+ * console.log(`${stage}: ${current}/${total} (${Math.floor(current/total*100)}%)`);
657
+ * }
655
658
  * });
656
659
  * ```
657
660
  */
@@ -659,6 +662,8 @@ declare class OpenDisplayDevice {
659
662
  refreshMode?: RefreshMode;
660
663
  ditherMode?: DitherMode;
661
664
  compress?: boolean;
665
+ onProgress?: (current: number, total: number, stage: string) => void;
666
+ onStatusChange?: (message: string) => void;
662
667
  }): Promise<void>;
663
668
  /**
664
669
  * Execute image upload using compressed or uncompressed protocol.
@@ -673,6 +678,8 @@ declare class OpenDisplayDevice {
673
678
  * - Progress logging
674
679
  *
675
680
  * @param imageData - Data to send in chunks
681
+ * @param onProgress - Optional progress callback (current bytes, total bytes, stage)
682
+ * @param onStatusChange - Optional status message callback
676
683
  * @returns True if device auto-completed (sent 0x0072 END early), false if all chunks sent normally
677
684
  * @throws {ProtocolError} If unexpected response received
678
685
  * @throws {BLETimeoutError} If no response within timeout
package/dist/index.d.ts CHANGED
@@ -651,7 +651,10 @@ declare class OpenDisplayDevice {
651
651
  * await device.uploadImage(imageData, {
652
652
  * refreshMode: RefreshMode.FULL,
653
653
  * ditherMode: DitherMode.BURKES,
654
- * compress: true
654
+ * compress: true,
655
+ * onProgress: (current, total, stage) => {
656
+ * console.log(`${stage}: ${current}/${total} (${Math.floor(current/total*100)}%)`);
657
+ * }
655
658
  * });
656
659
  * ```
657
660
  */
@@ -659,6 +662,8 @@ declare class OpenDisplayDevice {
659
662
  refreshMode?: RefreshMode;
660
663
  ditherMode?: DitherMode;
661
664
  compress?: boolean;
665
+ onProgress?: (current: number, total: number, stage: string) => void;
666
+ onStatusChange?: (message: string) => void;
662
667
  }): Promise<void>;
663
668
  /**
664
669
  * Execute image upload using compressed or uncompressed protocol.
@@ -673,6 +678,8 @@ declare class OpenDisplayDevice {
673
678
  * - Progress logging
674
679
  *
675
680
  * @param imageData - Data to send in chunks
681
+ * @param onProgress - Optional progress callback (current bytes, total bytes, stage)
682
+ * @param onStatusChange - Optional status message callback
676
683
  * @returns True if device auto-completed (sent 0x0072 END early), false if all chunks sent normally
677
684
  * @throws {ProtocolError} If unexpected response received
678
685
  * @throws {BLETimeoutError} If no response within timeout
package/dist/index.js CHANGED
@@ -1660,7 +1660,10 @@ var OpenDisplayDevice = class _OpenDisplayDevice {
1660
1660
  * await device.uploadImage(imageData, {
1661
1661
  * refreshMode: RefreshMode.FULL,
1662
1662
  * ditherMode: DitherMode.BURKES,
1663
- * compress: true
1663
+ * compress: true,
1664
+ * onProgress: (current, total, stage) => {
1665
+ * console.log(`${stage}: ${current}/${total} (${Math.floor(current/total*100)}%)`);
1666
+ * }
1664
1667
  * });
1665
1668
  * ```
1666
1669
  */
@@ -1670,9 +1673,12 @@ var OpenDisplayDevice = class _OpenDisplayDevice {
1670
1673
  const refreshMode = options.refreshMode ?? 0 /* FULL */;
1671
1674
  const ditherMode = options.ditherMode ?? DitherMode2.BURKES;
1672
1675
  const compress = options.compress ?? true;
1676
+ const onProgress = options.onProgress;
1677
+ const onStatusChange = options.onStatusChange;
1673
1678
  console.log(
1674
1679
  `Uploading image (${this.width}x${this.height}, ${ColorScheme4[this.colorScheme]})`
1675
1680
  );
1681
+ onStatusChange?.("Preparing image...");
1676
1682
  const encodedData = prepareImageForUpload(
1677
1683
  imageData,
1678
1684
  this.width,
@@ -1682,27 +1688,44 @@ var OpenDisplayDevice = class _OpenDisplayDevice {
1682
1688
  );
1683
1689
  let compressedData = null;
1684
1690
  if (compress) {
1691
+ onStatusChange?.("Compressing...");
1685
1692
  compressedData = compressImageData(encodedData, 6);
1686
1693
  if (compressedData.length < MAX_COMPRESSED_SIZE) {
1687
1694
  console.log(`Using compressed upload protocol (size: ${compressedData.length} bytes)`);
1695
+ onStatusChange?.("Uploading...");
1688
1696
  await this.executeUpload({
1689
1697
  imageData: encodedData,
1690
1698
  refreshMode,
1691
1699
  useCompression: true,
1692
1700
  compressedData,
1693
- uncompressedSize: encodedData.length
1701
+ uncompressedSize: encodedData.length,
1702
+ onProgress,
1703
+ onStatusChange
1694
1704
  });
1695
1705
  } else {
1696
1706
  console.log(
1697
1707
  `Compressed size exceeds ${MAX_COMPRESSED_SIZE} bytes, using uncompressed protocol`
1698
1708
  );
1699
- await this.executeUpload({ imageData: encodedData, refreshMode });
1709
+ onStatusChange?.("Uploading...");
1710
+ await this.executeUpload({
1711
+ imageData: encodedData,
1712
+ refreshMode,
1713
+ onProgress,
1714
+ onStatusChange
1715
+ });
1700
1716
  }
1701
1717
  } else {
1702
1718
  console.log("Compression disabled, using uncompressed protocol");
1703
- await this.executeUpload({ imageData: encodedData, refreshMode });
1719
+ onStatusChange?.("Uploading...");
1720
+ await this.executeUpload({
1721
+ imageData: encodedData,
1722
+ refreshMode,
1723
+ onProgress,
1724
+ onStatusChange
1725
+ });
1704
1726
  }
1705
1727
  console.log("Image upload complete");
1728
+ onStatusChange?.("Upload complete!");
1706
1729
  }
1707
1730
  /**
1708
1731
  * Execute image upload using compressed or uncompressed protocol.
@@ -1713,7 +1736,9 @@ var OpenDisplayDevice = class _OpenDisplayDevice {
1713
1736
  refreshMode,
1714
1737
  useCompression = false,
1715
1738
  compressedData,
1716
- uncompressedSize
1739
+ uncompressedSize,
1740
+ onProgress,
1741
+ onStatusChange
1717
1742
  } = params;
1718
1743
  let startCmd;
1719
1744
  let remainingCompressed = null;
@@ -1732,11 +1757,12 @@ var OpenDisplayDevice = class _OpenDisplayDevice {
1732
1757
  validateAckResponse(response, 112 /* DIRECT_WRITE_START */);
1733
1758
  let autoCompleted = false;
1734
1759
  if (useCompression && remainingCompressed && remainingCompressed.length > 0) {
1735
- autoCompleted = await this.sendDataChunks(remainingCompressed);
1760
+ autoCompleted = await this.sendDataChunks(remainingCompressed, onProgress, onStatusChange);
1736
1761
  } else if (!useCompression) {
1737
- autoCompleted = await this.sendDataChunks(imageData);
1762
+ autoCompleted = await this.sendDataChunks(imageData, onProgress, onStatusChange);
1738
1763
  }
1739
1764
  if (!autoCompleted) {
1765
+ onStatusChange?.("Refreshing display...");
1740
1766
  const endCmd = buildDirectWriteEndCommand(refreshMode);
1741
1767
  await this.connection.writeCommand(endCmd);
1742
1768
  response = await this.connection.readResponse(
@@ -1754,11 +1780,13 @@ var OpenDisplayDevice = class _OpenDisplayDevice {
1754
1780
  * - Progress logging
1755
1781
  *
1756
1782
  * @param imageData - Data to send in chunks
1783
+ * @param onProgress - Optional progress callback (current bytes, total bytes, stage)
1784
+ * @param onStatusChange - Optional status message callback
1757
1785
  * @returns True if device auto-completed (sent 0x0072 END early), false if all chunks sent normally
1758
1786
  * @throws {ProtocolError} If unexpected response received
1759
1787
  * @throws {BLETimeoutError} If no response within timeout
1760
1788
  */
1761
- async sendDataChunks(imageData) {
1789
+ async sendDataChunks(imageData, onProgress, onStatusChange) {
1762
1790
  let bytesSent = 0;
1763
1791
  let chunksSent = 0;
1764
1792
  while (bytesSent < imageData.length) {
@@ -1779,6 +1807,7 @@ var OpenDisplayDevice = class _OpenDisplayDevice {
1779
1807
  console.log(
1780
1808
  `No response after chunk ${chunksSent} (${(bytesSent / imageData.length * 100).toFixed(1)}%), waiting for device refresh...`
1781
1809
  );
1810
+ onStatusChange?.("Refreshing display...");
1782
1811
  response = await this.connection.readResponse(
1783
1812
  _OpenDisplayDevice.TIMEOUT_REFRESH
1784
1813
  );
@@ -1788,10 +1817,12 @@ var OpenDisplayDevice = class _OpenDisplayDevice {
1788
1817
  }
1789
1818
  const [command, isAck] = checkResponseType(response);
1790
1819
  if (command === 113 /* DIRECT_WRITE_DATA */) {
1820
+ onProgress?.(bytesSent, imageData.length, "upload");
1791
1821
  } else if (command === 114 /* DIRECT_WRITE_END */) {
1792
1822
  console.log(
1793
1823
  `Received END response after chunk ${chunksSent} - device auto-completed`
1794
1824
  );
1825
+ onProgress?.(imageData.length, imageData.length, "upload");
1795
1826
  return true;
1796
1827
  } else {
1797
1828
  throw new ProtocolError(