@fedejm/capacitor-esc-pos-printer 0.2.0 → 0.2.2

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.
@@ -43,6 +43,10 @@ import java.lang.reflect.InvocationTargetException;
43
43
  import java.util.HashMap;
44
44
  import java.util.Map;
45
45
  import java.util.UUID;
46
+ import java.util.concurrent.ConcurrentHashMap;
47
+ import java.util.concurrent.ExecutorService;
48
+ import java.util.concurrent.Executors;
49
+ import java.util.concurrent.ThreadFactory;
46
50
 
47
51
  @SuppressWarnings("unused")
48
52
  @CapacitorPlugin(
@@ -63,6 +67,17 @@ public class EscPosPrinterPlugin extends Plugin {
63
67
 
64
68
  private BluetoothAdapter bluetoothAdapter;
65
69
  private HashMap<String, BasePrinter> printersMap = new HashMap<>();
70
+
71
+ /**
72
+ * Per-printer single-thread executors.
73
+ *
74
+ * Goals:
75
+ * - Allow concurrent printing to different printers (e.g. ticket + labels).
76
+ * - Preserve ordering and prevent interleaving for the SAME printer.
77
+ *
78
+ * Keyed by the Capacitor printer hashKey (created by createPrinter()).
79
+ */
80
+ private final Map<String, ExecutorService> printerExecutors = new ConcurrentHashMap<>();
66
81
 
67
82
  // USB permission request tracking
68
83
  private final Map<String, PluginCall> pendingUsbPermissionCalls = new HashMap<>();
@@ -83,6 +98,16 @@ public class EscPosPrinterPlugin extends Plugin {
83
98
  protected void handleOnDestroy() {
84
99
  super.handleOnDestroy();
85
100
  unregisterUsbPermissionReceiver();
101
+
102
+ // Stop all per-printer executors (best-effort). Any pending JS calls are moot during teardown.
103
+ for (ExecutorService executor : printerExecutors.values()) {
104
+ try {
105
+ executor.shutdownNow();
106
+ } catch (Exception ignored) {
107
+ // ignore
108
+ }
109
+ }
110
+ printerExecutors.clear();
86
111
 
87
112
  // Clear any pending permission calls
88
113
  for (PluginCall call : pendingUsbPermissionCalls.values()) {
@@ -529,6 +554,18 @@ public class EscPosPrinterPlugin extends Plugin {
529
554
  }
530
555
  }
531
556
 
557
+ // Gracefully stop executor for this printer (let queued sends drain).
558
+ if (hashKey != null) {
559
+ var executor = printerExecutors.remove(hashKey);
560
+ if (executor != null) {
561
+ try {
562
+ executor.shutdown();
563
+ } catch (Exception ignored) {
564
+ // ignore
565
+ }
566
+ }
567
+ }
568
+
532
569
  var data = new JSObject();
533
570
  data.put("value", hasPrinter);
534
571
  call.resolve(data);
@@ -587,8 +624,15 @@ public class EscPosPrinterPlugin extends Plugin {
587
624
  @SuppressWarnings("unused")
588
625
  @PluginMethod
589
626
  public void sendToPrinter(PluginCall call) {
590
- var printer = getGuardedPrinterByHash(call);
627
+ var hashKey = call.getString("hashKey");
628
+ if (hashKey == null) {
629
+ call.reject("hashKey is required.");
630
+ return;
631
+ }
632
+
633
+ var printer = printersMap.get(hashKey);
591
634
  if (printer == null) {
635
+ call.reject("Printer with hash " + hashKey + " not found.");
592
636
  return;
593
637
  }
594
638
 
@@ -600,13 +644,32 @@ public class EscPosPrinterPlugin extends Plugin {
600
644
  bytesArray[i] = (byte)data.optInt(i);
601
645
  }
602
646
 
603
- try {
604
- printer.send(bytesArray, waitingTime);
647
+ // Serialize per-printer sends, but allow concurrency across printers.
648
+ // This prevents long ticket prints from blocking label printers.
649
+ final int finalWaitingTime = waitingTime != null ? waitingTime : 0;
650
+ final byte[] finalBytes = bytesArray;
605
651
 
606
- call.resolve();
607
- } catch (PrinterException e) {
608
- rejectWithPrinterException(call, e);
609
- }
652
+ var executor = printerExecutors.computeIfAbsent(hashKey, (key) -> {
653
+ final String suffix = key.length() > 8 ? key.substring(0, 8) : key;
654
+ ThreadFactory tf = r -> {
655
+ Thread t = new Thread(r);
656
+ t.setName("EscPosPrinter-" + suffix);
657
+ t.setDaemon(true);
658
+ return t;
659
+ };
660
+ return Executors.newSingleThreadExecutor(tf);
661
+ });
662
+
663
+ executor.execute(() -> {
664
+ try {
665
+ printer.send(finalBytes, finalWaitingTime);
666
+ call.resolve();
667
+ } catch (PrinterException e) {
668
+ rejectWithPrinterException(call, e);
669
+ } catch (Exception e) {
670
+ call.reject(e.getMessage() != null ? e.getMessage() : "Unknown error");
671
+ }
672
+ });
610
673
  }
611
674
 
612
675
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedejm/capacitor-esc-pos-printer",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "CapacitorJS wrapper for ESC POS (native) printers.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",