@munchi_oy/react-native-epson-printer 1.0.5 → 1.0.7
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/android/src/main/java/com/munchiepsonprinter/MunchiEpsonModule.java +236 -122
- package/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/index.js +7 -7
- package/dist/index.mjs +7 -7
- package/dist/utils/errorUtils.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/ios/Vendors/Epson/MunchiEpsonModule.swift +52 -0
- package/package.json +1 -1
|
@@ -44,6 +44,13 @@ import java.util.IdentityHashMap;
|
|
|
44
44
|
import java.util.Map;
|
|
45
45
|
import java.util.Set;
|
|
46
46
|
import java.util.UUID;
|
|
47
|
+
import java.util.concurrent.Callable;
|
|
48
|
+
import java.util.concurrent.ExecutionException;
|
|
49
|
+
import java.util.concurrent.ExecutorService;
|
|
50
|
+
import java.util.concurrent.Executors;
|
|
51
|
+
import java.util.concurrent.Future;
|
|
52
|
+
import java.util.concurrent.TimeUnit;
|
|
53
|
+
import java.util.concurrent.TimeoutException;
|
|
47
54
|
|
|
48
55
|
public class MunchiEpsonModule extends ReactContextBaseJavaModule implements ConnectionListener, StatusChangeListener, ReceiveListener, DiscoveryListener {
|
|
49
56
|
private static final String MODULE_NAME = "MunchiEpsonModule";
|
|
@@ -52,12 +59,19 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
52
59
|
private static final String EVENT_PRINTER_RECEIVE = "onPrinterReceive";
|
|
53
60
|
|
|
54
61
|
private static final int DEFAULT_DISCOVERY_TIMEOUT_MS = 5000;
|
|
62
|
+
private static final int DEFAULT_CONNECT_TIMEOUT_MS = 5000;
|
|
55
63
|
private static final int PRINT_TIMEOUT_MS = 30000;
|
|
56
64
|
private static final int CONNECTION_CACHE_TTL_MS = 120000;
|
|
65
|
+
private static final int STATUS_OPERATION_TIMEOUT_MS = 3000;
|
|
66
|
+
private static final int CACHE_HEALTH_CHECK_TIMEOUT_MS = 800;
|
|
67
|
+
private static final int SEND_OPERATION_TIMEOUT_MS = 5000;
|
|
68
|
+
private static final String RECONNECT_REQUIRED_CODE = "PRINTER_RECONNECT_REQUIRED";
|
|
69
|
+
private static final String RECONNECT_REQUIRED_MESSAGE = "Printer connection was lost. Reconnect the printer in Android Bluetooth settings, then try again.";
|
|
57
70
|
|
|
58
71
|
private final ReactApplicationContext reactContext;
|
|
59
72
|
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
|
60
73
|
private final Object lock = new Object();
|
|
74
|
+
private final ExecutorService printerExecutor = Executors.newCachedThreadPool();
|
|
61
75
|
|
|
62
76
|
private final Map<String, EpsonSession> sessions = new HashMap<>();
|
|
63
77
|
private final Map<Printer, String> printerToSessionId = new IdentityHashMap<>();
|
|
@@ -167,6 +181,7 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
167
181
|
public void connect(String sessionId, String target, double timeout, double model, double lang, Promise promise) {
|
|
168
182
|
int safeModel = normalizeModel((int) model);
|
|
169
183
|
int safeLang = normalizeLanguage((int) lang);
|
|
184
|
+
int safeTimeout = normalizeConnectTimeout((int) timeout);
|
|
170
185
|
|
|
171
186
|
EpsonSession session;
|
|
172
187
|
EpsonSession ownerSessionToReclaim = null;
|
|
@@ -210,69 +225,67 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
210
225
|
|
|
211
226
|
teardownPrinter(session, true);
|
|
212
227
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (cachedConnection.model == safeModel
|
|
216
|
-
&& cachedConnection.lang == safeLang
|
|
217
|
-
&& isConnectionHealthy(cachedConnection.printer)) {
|
|
218
|
-
printer = cachedConnection.printer;
|
|
219
|
-
} else {
|
|
220
|
-
disconnectPrinterQuietly(cachedConnection.printer);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
228
|
+
printerExecutor.execute(() -> {
|
|
229
|
+
Printer printer = null;
|
|
223
230
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
+
try {
|
|
232
|
+
if (cachedConnection != null) {
|
|
233
|
+
if (cachedConnection.model == safeModel && cachedConnection.lang == safeLang) {
|
|
234
|
+
if (isBluetoothTarget(target)) {
|
|
235
|
+
disconnectPrinterQuietly(cachedConnection.printer);
|
|
236
|
+
} else if (isConnectionHealthy(cachedConnection.printer, CACHE_HEALTH_CHECK_TIMEOUT_MS)) {
|
|
237
|
+
printer = cachedConnection.printer;
|
|
238
|
+
} else {
|
|
239
|
+
disconnectPrinterQuietly(cachedConnection.printer);
|
|
240
|
+
}
|
|
241
|
+
} else {
|
|
242
|
+
disconnectPrinterQuietly(cachedConnection.printer);
|
|
243
|
+
}
|
|
231
244
|
}
|
|
232
245
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
246
|
+
if (printer == null) {
|
|
247
|
+
Printer freshPrinter = new Printer(safeModel, safeLang, reactContext.getApplicationContext());
|
|
248
|
+
printer = freshPrinter;
|
|
249
|
+
freshPrinter.setConnectionEventListener(this);
|
|
250
|
+
freshPrinter.setStatusChangeEventListener(this);
|
|
251
|
+
freshPrinter.setReceiveEventListener(this);
|
|
252
|
+
runPrinterCall(() -> {
|
|
253
|
+
freshPrinter.connect(target, safeTimeout);
|
|
254
|
+
return null;
|
|
255
|
+
}, safeTimeout);
|
|
256
|
+
freshPrinter.startMonitor();
|
|
257
|
+
}
|
|
243
258
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
} catch (Exception error) {
|
|
252
|
-
if (printer != null) {
|
|
253
|
-
disconnectPrinterQuietly(printer);
|
|
254
|
-
}
|
|
255
|
-
rejectWithEposError(promise, "CONNECT_ERROR", "Failed to connect", error);
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
259
|
+
synchronized (lock) {
|
|
260
|
+
EpsonSession latestSession = sessions.get(sessionId);
|
|
261
|
+
if (latestSession == null) {
|
|
262
|
+
disconnectPrinterQuietly(printer);
|
|
263
|
+
promise.reject("SESSION_ERROR", "Session disposed while connecting");
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
258
266
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
267
|
+
latestSession.printer = printer;
|
|
268
|
+
latestSession.target = target;
|
|
269
|
+
latestSession.model = safeModel;
|
|
270
|
+
latestSession.lang = safeLang;
|
|
271
|
+
printerToSessionId.put(printer, sessionId);
|
|
272
|
+
targetToSessionId.put(target, sessionId);
|
|
273
|
+
}
|
|
266
274
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
targetToSessionId.put(target, sessionId);
|
|
273
|
-
}
|
|
275
|
+
promise.resolve(null);
|
|
276
|
+
} catch (Exception error) {
|
|
277
|
+
if (printer != null) {
|
|
278
|
+
disconnectPrinterQuietly(printer);
|
|
279
|
+
}
|
|
274
280
|
|
|
275
|
-
|
|
281
|
+
if (requiresReconnectInstruction(target, error)) {
|
|
282
|
+
promise.reject(RECONNECT_REQUIRED_CODE, RECONNECT_REQUIRED_MESSAGE);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
rejectWithEposError(promise, "CONNECT_ERROR", "Failed to connect", error);
|
|
287
|
+
}
|
|
288
|
+
});
|
|
276
289
|
}
|
|
277
290
|
|
|
278
291
|
@ReactMethod
|
|
@@ -295,6 +308,7 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
295
308
|
public void print(String sessionId, ReadableArray commands, Promise promise) {
|
|
296
309
|
EpsonSession session;
|
|
297
310
|
Printer printer;
|
|
311
|
+
String target;
|
|
298
312
|
synchronized (lock) {
|
|
299
313
|
session = sessions.get(sessionId);
|
|
300
314
|
if (session == null || session.printer == null) {
|
|
@@ -306,65 +320,80 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
306
320
|
return;
|
|
307
321
|
}
|
|
308
322
|
printer = session.printer;
|
|
323
|
+
target = session.target;
|
|
309
324
|
}
|
|
310
325
|
|
|
311
|
-
if (!ensureBluetoothOperationReadiness(
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
PrinterStatusInfo status;
|
|
316
|
-
try {
|
|
317
|
-
status = printer.getStatus();
|
|
318
|
-
} catch (Exception error) {
|
|
319
|
-
detachUnhealthyPrinter(sessionId, printer);
|
|
320
|
-
rejectWithEposError(promise, "PRINT_ERROR", "Printer is not reachable", error);
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (!isStatusReady(status)) {
|
|
325
|
-
detachUnhealthyPrinter(sessionId, printer);
|
|
326
|
-
promise.reject("PRINTER_OFFLINE", "Printer is offline or unreachable");
|
|
326
|
+
if (!ensureBluetoothOperationReadiness(target, promise)) {
|
|
327
327
|
return;
|
|
328
328
|
}
|
|
329
329
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
330
|
+
printerExecutor.execute(() -> {
|
|
331
|
+
try {
|
|
332
|
+
PrinterStatusInfo status = runPrinterCall(printer::getStatus, STATUS_OPERATION_TIMEOUT_MS);
|
|
333
|
+
if (!isStatusReady(status)) {
|
|
334
|
+
detachUnhealthyPrinter(sessionId, printer);
|
|
335
|
+
promise.reject("PRINTER_OFFLINE", "Printer is offline or unreachable");
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
337
338
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
339
|
+
printer.clearCommandBuffer();
|
|
340
|
+
applyCommands(printer, commands);
|
|
341
|
+
} catch (Exception error) {
|
|
342
|
+
detachUnhealthyPrinter(sessionId, printer);
|
|
343
|
+
if (requiresReconnectInstruction(target, error)) {
|
|
344
|
+
promise.reject(RECONNECT_REQUIRED_CODE, RECONNECT_REQUIRED_MESSAGE);
|
|
345
|
+
} else if (error instanceof Epos2Exception) {
|
|
346
|
+
rejectWithEposError(promise, "PRINT_ERROR", "Printer is not reachable", error);
|
|
347
|
+
} else {
|
|
348
|
+
rejectWithEposError(promise, "PRINT_ERROR", "Failed to build print data", error);
|
|
349
|
+
}
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
344
352
|
|
|
345
|
-
try {
|
|
346
|
-
printer.sendData(Printer.PARAM_DEFAULT);
|
|
347
|
-
} catch (Exception error) {
|
|
348
|
-
detachUnhealthyPrinter(sessionId, printer);
|
|
349
|
-
Promise pending = null;
|
|
350
353
|
synchronized (lock) {
|
|
351
354
|
EpsonSession latestSession = sessions.get(sessionId);
|
|
352
|
-
if (latestSession !=
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
latestSession.printPromise = null;
|
|
356
|
-
latestSession.printTimeoutRunnable = null;
|
|
355
|
+
if (latestSession == null || latestSession.printer != printer) {
|
|
356
|
+
promise.reject("PRINT_ERROR", "Printer not connected");
|
|
357
|
+
return;
|
|
357
358
|
}
|
|
359
|
+
latestSession.printPromise = promise;
|
|
360
|
+
Runnable timeoutRunnable = () -> handlePrintTimeout(sessionId);
|
|
361
|
+
latestSession.printTimeoutRunnable = timeoutRunnable;
|
|
362
|
+
mainHandler.postDelayed(timeoutRunnable, PRINT_TIMEOUT_MS);
|
|
358
363
|
}
|
|
359
|
-
|
|
360
|
-
|
|
364
|
+
|
|
365
|
+
try {
|
|
366
|
+
runPrinterCall(() -> {
|
|
367
|
+
printer.sendData(Printer.PARAM_DEFAULT);
|
|
368
|
+
return null;
|
|
369
|
+
}, SEND_OPERATION_TIMEOUT_MS);
|
|
370
|
+
} catch (Exception error) {
|
|
371
|
+
detachUnhealthyPrinter(sessionId, printer);
|
|
372
|
+
Promise pending = null;
|
|
373
|
+
synchronized (lock) {
|
|
374
|
+
EpsonSession latestSession = sessions.get(sessionId);
|
|
375
|
+
if (latestSession != null) {
|
|
376
|
+
pending = latestSession.printPromise;
|
|
377
|
+
cancelPrintTimeoutLocked(latestSession);
|
|
378
|
+
latestSession.printPromise = null;
|
|
379
|
+
latestSession.printTimeoutRunnable = null;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
if (pending != null) {
|
|
383
|
+
if (requiresReconnectInstruction(target, error)) {
|
|
384
|
+
pending.reject(RECONNECT_REQUIRED_CODE, RECONNECT_REQUIRED_MESSAGE);
|
|
385
|
+
} else {
|
|
386
|
+
rejectWithEposError(pending, "PRINT_ERROR", "Failed to send data", error);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
361
389
|
}
|
|
362
|
-
}
|
|
390
|
+
});
|
|
363
391
|
}
|
|
364
392
|
|
|
365
393
|
@ReactMethod
|
|
366
394
|
public void getStatus(String sessionId, Promise promise) {
|
|
367
395
|
EpsonSession session;
|
|
396
|
+
Printer printer;
|
|
368
397
|
synchronized (lock) {
|
|
369
398
|
session = sessions.get(sessionId);
|
|
370
399
|
}
|
|
@@ -374,30 +403,39 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
374
403
|
return;
|
|
375
404
|
}
|
|
376
405
|
|
|
406
|
+
printer = session.printer;
|
|
407
|
+
|
|
377
408
|
if (!ensureBluetoothOperationReadiness(session.target, promise)) {
|
|
378
409
|
return;
|
|
379
410
|
}
|
|
380
411
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
WritableMap statusMap = Arguments.createMap();
|
|
389
|
-
boolean paperEmpty = status.getPaper() == Printer.PAPER_EMPTY;
|
|
390
|
-
statusMap.putBoolean("online", isStatusReady(status));
|
|
391
|
-
statusMap.putBoolean("coverOpen", status.getCoverOpen() == Printer.TRUE);
|
|
392
|
-
statusMap.putBoolean("paperEmpty", paperEmpty);
|
|
393
|
-
statusMap.putString("paper", mapPaperStatus(status.getPaper()));
|
|
394
|
-
statusMap.putBoolean("drawerOpen", status.getDrawer() == Printer.DRAWER_HIGH);
|
|
395
|
-
statusMap.putString("errorStatus", mapErrorStatus(status.getErrorStatus()));
|
|
412
|
+
printerExecutor.execute(() -> {
|
|
413
|
+
try {
|
|
414
|
+
PrinterStatusInfo status = runPrinterCall(printer::getStatus, STATUS_OPERATION_TIMEOUT_MS);
|
|
415
|
+
if (status == null) {
|
|
416
|
+
promise.reject("STATUS_ERROR", "Failed to retrieve status");
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
396
419
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
420
|
+
WritableMap statusMap = Arguments.createMap();
|
|
421
|
+
boolean paperEmpty = status.getPaper() == Printer.PAPER_EMPTY;
|
|
422
|
+
statusMap.putBoolean("online", isStatusReady(status));
|
|
423
|
+
statusMap.putBoolean("coverOpen", status.getCoverOpen() == Printer.TRUE);
|
|
424
|
+
statusMap.putBoolean("paperEmpty", paperEmpty);
|
|
425
|
+
statusMap.putString("paper", mapPaperStatus(status.getPaper()));
|
|
426
|
+
statusMap.putBoolean("drawerOpen", status.getDrawer() == Printer.DRAWER_HIGH);
|
|
427
|
+
statusMap.putString("errorStatus", mapErrorStatus(status.getErrorStatus()));
|
|
428
|
+
|
|
429
|
+
promise.resolve(statusMap);
|
|
430
|
+
} catch (Exception error) {
|
|
431
|
+
detachUnhealthyPrinter(sessionId, printer);
|
|
432
|
+
if (requiresReconnectInstruction(session.target, error)) {
|
|
433
|
+
promise.reject(RECONNECT_REQUIRED_CODE, RECONNECT_REQUIRED_MESSAGE);
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
rejectWithEposError(promise, "STATUS_ERROR", "Failed to retrieve status", error);
|
|
437
|
+
}
|
|
438
|
+
});
|
|
401
439
|
}
|
|
402
440
|
|
|
403
441
|
@Override
|
|
@@ -534,6 +572,8 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
534
572
|
clearDiscoveryStateLocked();
|
|
535
573
|
}
|
|
536
574
|
|
|
575
|
+
printerExecutor.shutdownNow();
|
|
576
|
+
|
|
537
577
|
super.invalidate();
|
|
538
578
|
}
|
|
539
579
|
|
|
@@ -624,6 +664,10 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
624
664
|
}
|
|
625
665
|
|
|
626
666
|
if (disconnect && target != null && model >= 0 && lang >= 0) {
|
|
667
|
+
if (isBluetoothTarget(target)) {
|
|
668
|
+
disconnectPrinterQuietly(printer);
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
627
671
|
synchronized (lock) {
|
|
628
672
|
if (!targetToSessionId.containsKey(target)) {
|
|
629
673
|
cacheConnectionLocked(target, model, lang, printer);
|
|
@@ -676,9 +720,9 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
676
720
|
cachedConnections.clear();
|
|
677
721
|
}
|
|
678
722
|
|
|
679
|
-
private boolean isConnectionHealthy(Printer printer) {
|
|
723
|
+
private boolean isConnectionHealthy(Printer printer, int timeoutMs) {
|
|
680
724
|
try {
|
|
681
|
-
PrinterStatusInfo status = printer
|
|
725
|
+
PrinterStatusInfo status = runPrinterCall(printer::getStatus, timeoutMs);
|
|
682
726
|
return isStatusReady(status);
|
|
683
727
|
} catch (Exception ignored) {
|
|
684
728
|
return false;
|
|
@@ -915,18 +959,30 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
915
959
|
return;
|
|
916
960
|
}
|
|
917
961
|
|
|
962
|
+
int targetWidth = optionalInt(command, "width", bitmap.getWidth());
|
|
963
|
+
Bitmap printableBitmap = bitmap;
|
|
964
|
+
if (targetWidth > 0 && targetWidth != bitmap.getWidth()) {
|
|
965
|
+
int targetHeight = Math.max(1, Math.round((bitmap.getHeight() * (float) targetWidth) / bitmap.getWidth()));
|
|
966
|
+
printableBitmap = Bitmap.createScaledBitmap(bitmap, targetWidth, targetHeight, true);
|
|
967
|
+
}
|
|
968
|
+
|
|
918
969
|
printer.addImage(
|
|
919
|
-
|
|
970
|
+
printableBitmap,
|
|
920
971
|
0,
|
|
921
972
|
0,
|
|
922
|
-
|
|
923
|
-
|
|
973
|
+
printableBitmap.getWidth(),
|
|
974
|
+
printableBitmap.getHeight(),
|
|
924
975
|
Printer.COLOR_1,
|
|
925
976
|
Printer.MODE_MONO,
|
|
926
977
|
Printer.HALFTONE_DITHER,
|
|
927
978
|
Printer.PARAM_DEFAULT,
|
|
928
979
|
Printer.COMPRESS_AUTO
|
|
929
980
|
);
|
|
981
|
+
|
|
982
|
+
if (printableBitmap != bitmap) {
|
|
983
|
+
printableBitmap.recycle();
|
|
984
|
+
}
|
|
985
|
+
bitmap.recycle();
|
|
930
986
|
}
|
|
931
987
|
|
|
932
988
|
private boolean hasNumeric(ReadableMap map, String key) {
|
|
@@ -1060,6 +1116,58 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
1060
1116
|
|| locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
|
|
1061
1117
|
}
|
|
1062
1118
|
|
|
1119
|
+
private int normalizeConnectTimeout(int timeout) {
|
|
1120
|
+
if (timeout <= 0) {
|
|
1121
|
+
return DEFAULT_CONNECT_TIMEOUT_MS;
|
|
1122
|
+
}
|
|
1123
|
+
return timeout;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
private boolean requiresReconnectInstruction(String target, Exception error) {
|
|
1127
|
+
if (!isBluetoothTarget(target)) {
|
|
1128
|
+
return false;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
if (error instanceof PrinterOperationTimeoutException) {
|
|
1132
|
+
return true;
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
if (error instanceof Epos2Exception) {
|
|
1136
|
+
int status = ((Epos2Exception) error).getErrorStatus();
|
|
1137
|
+
return status == Epos2Exception.ERR_CONNECT
|
|
1138
|
+
|| status == Epos2Exception.ERR_TIMEOUT
|
|
1139
|
+
|| status == Epos2Exception.ERR_DISCONNECT
|
|
1140
|
+
|| status == Epos2Exception.ERR_PROCESSING
|
|
1141
|
+
|| status == Epos2Exception.ERR_FAILURE
|
|
1142
|
+
|| status == Epos2Exception.ERR_ILLEGAL;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
String message = String.valueOf(error.getMessage()).toUpperCase();
|
|
1146
|
+
return message.contains("DISCONNECT")
|
|
1147
|
+
|| message.contains("OFFLINE")
|
|
1148
|
+
|| message.contains("NOT CONNECTED");
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
private <T> T runPrinterCall(Callable<T> callable, int timeoutMs) throws Exception {
|
|
1152
|
+
Future<T> future = printerExecutor.submit(callable);
|
|
1153
|
+
try {
|
|
1154
|
+
return future.get(timeoutMs, TimeUnit.MILLISECONDS);
|
|
1155
|
+
} catch (TimeoutException error) {
|
|
1156
|
+
future.cancel(true);
|
|
1157
|
+
throw new PrinterOperationTimeoutException(timeoutMs, error);
|
|
1158
|
+
} catch (InterruptedException error) {
|
|
1159
|
+
future.cancel(true);
|
|
1160
|
+
Thread.currentThread().interrupt();
|
|
1161
|
+
throw error;
|
|
1162
|
+
} catch (ExecutionException error) {
|
|
1163
|
+
Throwable cause = error.getCause();
|
|
1164
|
+
if (cause instanceof Exception) {
|
|
1165
|
+
throw (Exception) cause;
|
|
1166
|
+
}
|
|
1167
|
+
throw new Exception(cause);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1063
1171
|
private int normalizeLanguage(int lang) {
|
|
1064
1172
|
if (lang >= 0 && lang <= 7) {
|
|
1065
1173
|
return lang;
|
|
@@ -1214,4 +1322,10 @@ public class MunchiEpsonModule extends ReactContextBaseJavaModule implements Con
|
|
|
1214
1322
|
this.printer = printer;
|
|
1215
1323
|
}
|
|
1216
1324
|
}
|
|
1325
|
+
|
|
1326
|
+
private static final class PrinterOperationTimeoutException extends Exception {
|
|
1327
|
+
PrinterOperationTimeoutException(int timeoutMs, Throwable cause) {
|
|
1328
|
+
super("Printer operation timed out after " + timeoutMs + "ms", cause);
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1217
1331
|
}
|
package/dist/errors.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export declare enum PrinterErrorCode {
|
|
|
7
7
|
UNKNOWN = "UNKNOWN"
|
|
8
8
|
}
|
|
9
9
|
export declare enum PrinterTranslationCode {
|
|
10
|
+
ERR_PRINTER_RECONNECT_REQUIRED = "printer.error.reconnect_required",
|
|
10
11
|
ERR_PRINTER_OFFLINE = "printer.error.offline",
|
|
11
12
|
ERR_PRINTER_BUSY = "printer.error.busy",
|
|
12
13
|
ERR_PRINTER_COVER_OPEN = "printer.error.cover_open",
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,oBAAY,gBAAgB;IAC1B,iBAAiB,sBAAsB;IACvC,YAAY,iBAAiB;IAC7B,gBAAgB,qBAAqB;IACrC,OAAO,YAAY;IACnB,qBAAqB,0BAA0B;IAC/C,OAAO,YAAY;CACpB;AAED,oBAAY,sBAAsB;IAChC,mBAAmB,0BAA0B;IAC7C,gBAAgB,uBAAuB;IACvC,sBAAsB,6BAA6B;IACnD,uBAAuB,8BAA8B;IACrD,sBAAsB,qCAAqC;IAC3D,WAAW,0BAA0B;CACtC;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAElC,IAAI,EAAE,gBAAgB;IACtB,eAAe,EAAE,sBAAsB;IAEvC,aAAa,CAAC,EAAE,OAAO;gBAHvB,IAAI,EAAE,gBAAgB,EACtB,eAAe,EAAE,sBAAsB,EAC9C,OAAO,EAAE,MAAM,EACR,aAAa,CAAC,EAAE,OAAO,YAAA;CAQjC"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,oBAAY,gBAAgB;IAC1B,iBAAiB,sBAAsB;IACvC,YAAY,iBAAiB;IAC7B,gBAAgB,qBAAqB;IACrC,OAAO,YAAY;IACnB,qBAAqB,0BAA0B;IAC/C,OAAO,YAAY;CACpB;AAED,oBAAY,sBAAsB;IAChC,8BAA8B,qCAAqC;IACnE,mBAAmB,0BAA0B;IAC7C,gBAAgB,uBAAuB;IACvC,sBAAsB,6BAA6B;IACnD,uBAAuB,8BAA8B;IACrD,sBAAsB,qCAAqC;IAC3D,WAAW,0BAA0B;CACtC;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAElC,IAAI,EAAE,gBAAgB;IACtB,eAAe,EAAE,sBAAsB;IAEvC,aAAa,CAAC,EAAE,OAAO;gBAHvB,IAAI,EAAE,gBAAgB,EACtB,eAAe,EAAE,sBAAsB,EAC9C,OAAO,EAAE,MAAM,EACR,aAAa,CAAC,EAAE,OAAO,YAAA;CAQjC"}
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
"use strict";var he=Object.create;var D=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var Ee=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var pe=(t,e)=>{for(var r in e)D(t,r,{get:e[r],enumerable:!0})},J=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ce(e))!Re.call(t,i)&&i!==r&&D(t,i,{get:()=>e[i],enumerable:!(n=fe(e,i))||n.enumerable});return t};var Pe=(t,e,r)=>(r=t!=null?he(Ee(t)):{},J(e||!t||!t.__esModule?D(r,"default",{value:t,enumerable:!0}):r,t)),Ne=t=>J(D({},"__esModule",{value:!0}),t);var Be={};pe(Be,{Epos2CallbackCode:()=>te,Epos2ConnectionEvent:()=>Z,Epos2ErrorStatus:()=>ee,Epos2Font:()=>re,Epos2Lang:()=>V,Epos2StatusEvent:()=>H,EpsonModel:()=>q,FontSize:()=>b,MunchiPrinterError:()=>h,PrinterError:()=>p,PrinterErrorCode:()=>y,PrinterProvider:()=>Ue,PrinterTranslationCode:()=>v,VERSION:()=>Te,discoverPrinters:()=>ce,getGlobalLogger:()=>Y,getPrinter:()=>K,resolveEpsonError:()=>Le,resolveModelFromBluetoothName:()=>le,resolvePrinterError:()=>de,setGlobalLogger:()=>B,usePrinter:()=>k,usePrinterStatus:()=>Fe});module.exports=Ne(Be);var j={},B=t=>{j.logger=t},Y=()=>j.logger;var W=require("react-native");var y=(l=>(l.CONNECTION_FAILED="CONNECTION_FAILED",l.PRINT_FAILED="PRINT_FAILED",l.DISCOVERY_FAILED="DISCOVERY_FAILED",l.TIMEOUT="TIMEOUT",l.NATIVE_MODULE_MISSING="NATIVE_MODULE_MISSING",l.UNKNOWN="UNKNOWN",l))(y||{}),v=(l=>(l.ERR_PRINTER_OFFLINE="printer.error.offline",l.ERR_PRINTER_BUSY="printer.error.busy",l.ERR_PRINTER_COVER_OPEN="printer.error.cover_open",l.ERR_PRINTER_PAPER_EMPTY="printer.error.paper_empty",l.ERR_CONNECTION_TIMEOUT="printer.error.connection_timeout",l.ERR_UNKNOWN="printer.error.unknown",l))(v||{}),h=class t extends Error{constructor(r,n,i,o){super(i);this.code=r;this.translationCode=n;this.originalError=o;this.name="MunchiPrinterError",Object.setPrototypeOf(this,t.prototype)}};var Ie=t=>{if(!t||typeof t!="object")return"";let e=t.code;return typeof e=="string"?e:""},Se=t=>{if(t instanceof Error)return t.message;if(t&&typeof t=="object"){let e=t.message;if(typeof e=="string")return e}return String(t)},T=(t,e,r)=>t.includes(r)||e===r||e.includes(r),E=t=>{if(t instanceof h)return t;let e=Se(t),r=Ie(t),n=e.toUpperCase(),i=r.toUpperCase();return n.includes("ERROR CODE: 4")?new h("PRINT_FAILED","printer.error.cover_open","Printer cover is open",t):n.includes("ERROR CODE: 3")?new h("PRINT_FAILED","printer.error.busy","Printer is performing auto-recovery",t):n.includes("ERROR CODE: 7")?new h("PRINT_FAILED","printer.error.paper_empty","Printer paper is empty",t):T(n,i,"TARGET_IN_USE")||T(n,i,"BUSY")||T(n,i,"IN_USE")||T(n,i,"PRINT_BUSY")||T(n,i,"DISCOVERY_BUSY")?new h("TIMEOUT","printer.error.busy","Printer is busy",t):T(n,i,"TIMEOUT")||T(n,i,"ERR_TIMEOUT")||T(n,i,"PRINT_TIMEOUT")?new h("TIMEOUT","printer.error.connection_timeout","Operation timed out",t):T(n,i,"PERMISSION_DENIED")||T(n,i,"LOCATION_DISABLED")||T(n,i,"BLUETOOTH_DISABLED")?new h("CONNECTION_FAILED","printer.error.offline",e,t):T(n,i,"DISCOVERY_ERROR")||n.includes("DISCOVERY")?new h("DISCOVERY_FAILED","printer.error.unknown",e,t):T(n,i,"PRINTER_OFFLINE")||T(n,i,"SESSION_ERROR")||T(n,i,"STATUS_ERROR")||T(n,i,"INIT_ERROR")||T(n,i,"PRINT_CANCELED")||T(n,i,"DISCONNECT")||T(n,i,"ERR_DISCONNECT")||n.includes("PRINTER NOT CONNECTED")||n.includes("OFFLINE")?new h("CONNECTION_FAILED","printer.error.offline",n.includes("OFFLINE")?e:"Printer disconnected",t):T(n,i,"CONNECT_ERROR")||n.includes("FAILED TO CONNECT")||T(n,i,"ERR_CONNECT")?new h("CONNECTION_FAILED","printer.error.offline","Failed to connect to printer",t):T(n,i,"PRINT_ERROR")||T(n,i,"PRINT_FAILURE")?new h("PRINT_FAILED","printer.error.unknown",e,t):new h("UNKNOWN","printer.error.unknown",e,t)};var H=(a=>(a[a.ONLINE=0]="ONLINE",a[a.OFFLINE=1]="OFFLINE",a[a.POWER_OFF=2]="POWER_OFF",a[a.COVER_CLOSE=3]="COVER_CLOSE",a[a.COVER_OPEN=4]="COVER_OPEN",a[a.PAPER_OK=5]="PAPER_OK",a[a.PAPER_NEAR_END=6]="PAPER_NEAR_END",a[a.PAPER_EMPTY=7]="PAPER_EMPTY",a[a.DRAWER_HIGH=8]="DRAWER_HIGH",a[a.DRAWER_LOW=9]="DRAWER_LOW",a[a.BATTERY_ENOUGH=10]="BATTERY_ENOUGH",a[a.BATTERY_EMPTY=11]="BATTERY_EMPTY",a[a.AUTO_RECOVER_ERROR=20]="AUTO_RECOVER_ERROR",a[a.AUTO_RECOVER_OK=21]="AUTO_RECOVER_OK",a[a.UNRECOVERABLE_ERROR=22]="UNRECOVERABLE_ERROR",a))(H||{}),Z=(n=>(n[n.RECONNECTING=0]="RECONNECTING",n[n.RECONNECT=1]="RECONNECT",n[n.DISCONNECT=2]="DISCONNECT",n))(Z||{}),ee=(u=>(u[u.SUCCESS=0]="SUCCESS",u[u.ERR_PARAM=1]="ERR_PARAM",u[u.ERR_CONNECT=2]="ERR_CONNECT",u[u.ERR_TIMEOUT=3]="ERR_TIMEOUT",u[u.ERR_MEMORY=4]="ERR_MEMORY",u[u.ERR_ILLEGAL=5]="ERR_ILLEGAL",u[u.ERR_PROCESSING=6]="ERR_PROCESSING",u[u.ERR_NOT_FOUND=7]="ERR_NOT_FOUND",u[u.ERR_IN_USE=8]="ERR_IN_USE",u[u.ERR_TYPE_INVALID=9]="ERR_TYPE_INVALID",u[u.ERR_DISCONNECT=10]="ERR_DISCONNECT",u[u.ERR_ALREADY_OPENED=11]="ERR_ALREADY_OPENED",u[u.ERR_ALREADY_USED=12]="ERR_ALREADY_USED",u[u.ERR_BOX_COUNT_OVER=13]="ERR_BOX_COUNT_OVER",u[u.ERR_BOX_CLIENT_OVER=14]="ERR_BOX_CLIENT_OVER",u[u.ERR_UNSUPPORTED=15]="ERR_UNSUPPORTED",u[u.ERR_DEVICE_BUSY=16]="ERR_DEVICE_BUSY",u[u.ERR_RECOVERY_FAILURE=17]="ERR_RECOVERY_FAILURE",u[u.ERR_FAILURE=255]="ERR_FAILURE",u))(ee||{}),te=(d=>(d[d.SUCCESS=0]="SUCCESS",d[d.ERR_TIMEOUT=1]="ERR_TIMEOUT",d[d.ERR_NOT_FOUND=2]="ERR_NOT_FOUND",d[d.ERR_AUTORECOVER=3]="ERR_AUTORECOVER",d[d.ERR_COVER_OPEN=4]="ERR_COVER_OPEN",d[d.ERR_CUTTER=5]="ERR_CUTTER",d[d.ERR_MECHANICAL=6]="ERR_MECHANICAL",d[d.ERR_EMPTY=7]="ERR_EMPTY",d[d.ERR_UNRECOVERABLE=8]="ERR_UNRECOVERABLE",d[d.ERR_SYSTEM=9]="ERR_SYSTEM",d[d.ERR_PORT=10]="ERR_PORT",d[d.ERR_FAILURE=255]="ERR_FAILURE",d))(te||{}),V=(c=>(c[c.EN=0]="EN",c[c.JA=1]="JA",c[c.ZH_CN=2]="ZH_CN",c[c.ZH_TW=3]="ZH_TW",c[c.KO=4]="KO",c[c.TH=5]="TH",c[c.VI=6]="VI",c[c.MULTI=7]="MULTI",c))(V||{}),re=(o=>(o[o.FONT_A=0]="FONT_A",o[o.FONT_B=1]="FONT_B",o[o.FONT_C=2]="FONT_C",o[o.FONT_D=3]="FONT_D",o[o.FONT_E=4]="FONT_E",o))(re||{}),q=(s=>(s[s.TM_M10=0]="TM_M10",s[s.TM_M30=1]="TM_M30",s[s.TM_P20=2]="TM_P20",s[s.TM_P60=3]="TM_P60",s[s.TM_P60II=4]="TM_P60II",s[s.TM_P80=5]="TM_P80",s[s.TM_T20=6]="TM_T20",s[s.TM_T60=7]="TM_T60",s[s.TM_T70=8]="TM_T70",s[s.TM_T81=9]="TM_T81",s[s.TM_T82=10]="TM_T82",s[s.TM_T83=11]="TM_T83",s[s.TM_T88=12]="TM_T88",s[s.TM_T90=13]="TM_T90",s[s.TM_T90KP=14]="TM_T90KP",s[s.TM_U220=15]="TM_U220",s[s.TM_U330=16]="TM_U330",s[s.TM_L90=17]="TM_L90",s[s.TM_H6000=18]="TM_H6000",s[s.TM_T83III=19]="TM_T83III",s[s.TM_T100=20]="TM_T100",s[s.TM_M30II=21]="TM_M30II",s[s.TM_M50=23]="TM_M50",s[s.TM_T88VII=24]="TM_T88VII",s[s.TM_L90LFC=25]="TM_L90LFC",s[s.TM_L100=26]="TM_L100",s[s.TM_P20II=27]="TM_P20II",s[s.TM_P80II=28]="TM_P80II",s[s.TM_M30III=29]="TM_M30III",s[s.TM_M50II=30]="TM_M50II",s[s.TM_M55=31]="TM_M55",s[s.TM_U220II=32]="TM_U220II",s))(q||{});var p=class t extends h{constructor(r,n,i,o,l){super(n,i,o,l);this.isHardwareError=r;this.name="PrinterError",Object.setPrototypeOf(this,t.prototype)}},z=t=>{if(t instanceof p)return t.isHardwareError;let e=String(t.message||t).toUpperCase();return e.includes("ERR_OFF_LINE")||e.includes("ERR_COVER_OPEN")||e.includes("ERR_PAPER_OUT")||e.includes("ERR_FAILURE")||e.includes("DISCONNECT")||e.includes("PRINT_TIMEOUT")||e.includes("ERROR CODE: 4")||e.includes("ERROR CODE: 7")||e.includes("ERROR CODE: 3")},ne=t=>{if(t instanceof p)return t;let e=E(t),r=z(t);return new p(r,e.code,e.translationCode,e.message,e.originalError)};var M=require("react-native"),m=M.NativeModules.MunchiEpsonModule,G=()=>m?new M.NativeEventEmitter(m):null,_e=t=>new Promise(e=>setTimeout(e,t)),Oe=t=>{if(!t||typeof t!="object")return"";let e=t.code;return typeof e=="string"?e.toUpperCase():""},ye=t=>{if(t instanceof Error)return t.message.toUpperCase();if(t&&typeof t=="object"){let e=t.message;if(typeof e=="string")return e.toUpperCase()}return String(t).toUpperCase()},P=(t,e,r)=>t.includes(r)||e===r||e.includes(r),S=async(t,e=3,r=500)=>{try{return await t()}catch(n){if(e<=1)throw n;let i=ye(n),o=Oe(n);if(P(i,o,"TARGET_IN_USE"))throw n;if(P(i,o,"BUSY")||P(i,o,"IN_USE")||P(i,o,"ERR_IN_USE")||P(i,o,"PRINT_BUSY")||P(i,o,"ERR_CONNECT")||P(i,o,"CONNECT_ERROR")||P(i,o,"ERR_TIMEOUT")||P(i,o,"PRINT_TIMEOUT"))return await _e(r),S(t,e-1,r);throw n}};var ve=new Set([0,3,5,21]),w=class{constructor(e){this.config=e}statusSubscription=null;connectionSubscription=null;connectionCallbacks=new Set;emitStatus(e){for(let r of this.connectionCallbacks)r(e)}ensureStatusListener(){if(this.statusSubscription)return;let e=G();e&&(this.config.logger?.info?.("[EpsonPrinter] Starting status listener for queue management"),this.statusSubscription=e.addListener("onPrinterStatusChange",r=>{if(!this.config.getSessionId()||r.sessionId!==this.config.getSessionId())return;let n=`[EpsonPrinter] Received Status Event: ${r.eventType}`;this.config.logger?.info?.(n),this.config.onEvent({connectionStatus:null,statusEventType:r.eventType,isRecoveryEvent:ve.has(r.eventType)})}))}ensureConnectionListener(){if(this.connectionSubscription)return;let e=G();e&&(this.connectionSubscription=e.addListener("onPrinterConnectionChange",r=>{if(!this.config.getSessionId()||r.sessionId!==this.config.getSessionId())return;let n="UNKNOWN";switch(r.status){case"RECONNECTING":n="RECONNECTING";break;case"RECONNECTED":n="CONNECTED";break;case"DISCONNECTED":n="DISCONNECTED";break;default:n="UNKNOWN"}this.config.onEvent({connectionStatus:n,statusEventType:null,isRecoveryEvent:!1}),this.emitStatus(n)}))}removeStatusListener(){this.statusSubscription&&(this.statusSubscription.remove(),this.statusSubscription=null)}onConnectionChange(e){return this.connectionCallbacks.add(e),e(this.config.getConnectionStatus()),this.ensureConnectionListener(),()=>{this.connectionCallbacks.delete(e),this.connectionCallbacks.size===0&&this.connectionSubscription&&(this.connectionSubscription.remove(),this.connectionSubscription=null)}}};var b=(n=>(n.Small="Small",n.Medium="Medium",n.Large="Large",n))(b||{});var De=(t,e=!1)=>{let r={Small:{normal:{width:1,height:1},item:{width:1,height:1}},Medium:{normal:{width:2,height:2},item:{width:2,height:2}},Large:{normal:{width:2,height:2},item:{width:3,height:3}}},n=e?"item":"normal";return r[t]?.[n]??r.Small.normal},ie=t=>{if(typeof t!="object"||t===null)return null;let e=t;return{target:String(e.target||""),name:String(e.name||""),macAddress:e.macAddress?String(e.macAddress):void 0,ipAddress:e.ipAddress?String(e.ipAddress):void 0,bdAddress:e.bdAddress?String(e.bdAddress):void 0,type:"EPSON"}},se=t=>t.commands.map(e=>{switch(e.type){case"text":return{cmd:"addText",data:e.text,align:e.align,bold:e.bold,underline:e.underline,size:e.size};case"align":return{cmd:"addTextAlign",align:e.align};case"bold":return{cmd:"addTextStyle",bold:e.value};case"fontSize":{let r=De(e.size,e.isItemName);return{cmd:"addTextSize",width:r.width,height:r.height}}case"newline":return{cmd:"addFeedLine",line:e.lines||1};case"separator":return{cmd:"addText",data:`------------------
|
|
1
|
+
"use strict";var he=Object.create;var D=Object.defineProperty;var Ee=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var fe=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var pe=(t,e)=>{for(var r in e)D(t,r,{get:e[r],enumerable:!0})},J=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ce(e))!Re.call(t,i)&&i!==r&&D(t,i,{get:()=>e[i],enumerable:!(n=Ee(e,i))||n.enumerable});return t};var Ne=(t,e,r)=>(r=t!=null?he(fe(t)):{},J(e||!t||!t.__esModule?D(r,"default",{value:t,enumerable:!0}):r,t)),Pe=t=>J(D({},"__esModule",{value:!0}),t);var Be={};pe(Be,{Epos2CallbackCode:()=>te,Epos2ConnectionEvent:()=>Z,Epos2ErrorStatus:()=>ee,Epos2Font:()=>re,Epos2Lang:()=>V,Epos2StatusEvent:()=>H,EpsonModel:()=>q,FontSize:()=>b,MunchiPrinterError:()=>h,PrinterError:()=>p,PrinterErrorCode:()=>y,PrinterProvider:()=>Ue,PrinterTranslationCode:()=>v,VERSION:()=>Te,discoverPrinters:()=>ce,getGlobalLogger:()=>Y,getPrinter:()=>K,resolveEpsonError:()=>Le,resolveModelFromBluetoothName:()=>le,resolvePrinterError:()=>de,setGlobalLogger:()=>B,usePrinter:()=>k,usePrinterStatus:()=>Fe});module.exports=Pe(Be);var j={},B=t=>{j.logger=t},Y=()=>j.logger;var W=require("react-native");var y=(T=>(T.CONNECTION_FAILED="CONNECTION_FAILED",T.PRINT_FAILED="PRINT_FAILED",T.DISCOVERY_FAILED="DISCOVERY_FAILED",T.TIMEOUT="TIMEOUT",T.NATIVE_MODULE_MISSING="NATIVE_MODULE_MISSING",T.UNKNOWN="UNKNOWN",T))(y||{}),v=(c=>(c.ERR_PRINTER_RECONNECT_REQUIRED="printer.error.reconnect_required",c.ERR_PRINTER_OFFLINE="printer.error.offline",c.ERR_PRINTER_BUSY="printer.error.busy",c.ERR_PRINTER_COVER_OPEN="printer.error.cover_open",c.ERR_PRINTER_PAPER_EMPTY="printer.error.paper_empty",c.ERR_CONNECTION_TIMEOUT="printer.error.connection_timeout",c.ERR_UNKNOWN="printer.error.unknown",c))(v||{}),h=class t extends Error{constructor(r,n,i,o){super(i);this.code=r;this.translationCode=n;this.originalError=o;this.name="MunchiPrinterError",Object.setPrototypeOf(this,t.prototype)}};var Ie=t=>{if(!t||typeof t!="object")return"";let e=t.code;return typeof e=="string"?e:""},Se=t=>{if(t instanceof Error)return t.message;if(t&&typeof t=="object"){let e=t.message;if(typeof e=="string")return e}return String(t)},g=(t,e,r)=>t.includes(r)||e===r||e.includes(r),f=t=>{if(t instanceof h)return t;let e=Se(t),r=Ie(t),n=e.toUpperCase(),i=r.toUpperCase();return n.includes("ERROR CODE: 4")?new h("PRINT_FAILED","printer.error.cover_open","Printer cover is open",t):n.includes("ERROR CODE: 3")?new h("PRINT_FAILED","printer.error.busy","Printer is performing auto-recovery",t):n.includes("ERROR CODE: 7")?new h("PRINT_FAILED","printer.error.paper_empty","Printer paper is empty",t):g(n,i,"TARGET_IN_USE")||g(n,i,"BUSY")||g(n,i,"IN_USE")||g(n,i,"PRINT_BUSY")||g(n,i,"DISCOVERY_BUSY")?new h("TIMEOUT","printer.error.busy","Printer is busy",t):g(n,i,"TIMEOUT")||g(n,i,"ERR_TIMEOUT")||g(n,i,"PRINT_TIMEOUT")?new h("TIMEOUT","printer.error.connection_timeout","Operation timed out",t):g(n,i,"PRINTER_RECONNECT_REQUIRED")||n.includes("RECONNECT THE PRINTER")?new h("CONNECTION_FAILED","printer.error.reconnect_required",e,t):g(n,i,"PERMISSION_DENIED")||g(n,i,"LOCATION_DISABLED")||g(n,i,"BLUETOOTH_DISABLED")?new h("CONNECTION_FAILED","printer.error.offline",e,t):g(n,i,"DISCOVERY_ERROR")||n.includes("DISCOVERY")?new h("DISCOVERY_FAILED","printer.error.unknown",e,t):g(n,i,"PRINTER_OFFLINE")||g(n,i,"SESSION_ERROR")||g(n,i,"STATUS_ERROR")||g(n,i,"INIT_ERROR")||g(n,i,"PRINT_CANCELED")||g(n,i,"DISCONNECT")||g(n,i,"ERR_DISCONNECT")||n.includes("PRINTER NOT CONNECTED")||n.includes("OFFLINE")?new h("CONNECTION_FAILED","printer.error.offline",n.includes("OFFLINE")?e:"Printer disconnected",t):g(n,i,"CONNECT_ERROR")||n.includes("FAILED TO CONNECT")||g(n,i,"ERR_CONNECT")?new h("CONNECTION_FAILED","printer.error.offline","Failed to connect to printer",t):g(n,i,"PRINT_ERROR")||g(n,i,"PRINT_FAILURE")?new h("PRINT_FAILED","printer.error.unknown",e,t):new h("UNKNOWN","printer.error.unknown",e,t)};var H=(a=>(a[a.ONLINE=0]="ONLINE",a[a.OFFLINE=1]="OFFLINE",a[a.POWER_OFF=2]="POWER_OFF",a[a.COVER_CLOSE=3]="COVER_CLOSE",a[a.COVER_OPEN=4]="COVER_OPEN",a[a.PAPER_OK=5]="PAPER_OK",a[a.PAPER_NEAR_END=6]="PAPER_NEAR_END",a[a.PAPER_EMPTY=7]="PAPER_EMPTY",a[a.DRAWER_HIGH=8]="DRAWER_HIGH",a[a.DRAWER_LOW=9]="DRAWER_LOW",a[a.BATTERY_ENOUGH=10]="BATTERY_ENOUGH",a[a.BATTERY_EMPTY=11]="BATTERY_EMPTY",a[a.AUTO_RECOVER_ERROR=20]="AUTO_RECOVER_ERROR",a[a.AUTO_RECOVER_OK=21]="AUTO_RECOVER_OK",a[a.UNRECOVERABLE_ERROR=22]="UNRECOVERABLE_ERROR",a))(H||{}),Z=(n=>(n[n.RECONNECTING=0]="RECONNECTING",n[n.RECONNECT=1]="RECONNECT",n[n.DISCONNECT=2]="DISCONNECT",n))(Z||{}),ee=(u=>(u[u.SUCCESS=0]="SUCCESS",u[u.ERR_PARAM=1]="ERR_PARAM",u[u.ERR_CONNECT=2]="ERR_CONNECT",u[u.ERR_TIMEOUT=3]="ERR_TIMEOUT",u[u.ERR_MEMORY=4]="ERR_MEMORY",u[u.ERR_ILLEGAL=5]="ERR_ILLEGAL",u[u.ERR_PROCESSING=6]="ERR_PROCESSING",u[u.ERR_NOT_FOUND=7]="ERR_NOT_FOUND",u[u.ERR_IN_USE=8]="ERR_IN_USE",u[u.ERR_TYPE_INVALID=9]="ERR_TYPE_INVALID",u[u.ERR_DISCONNECT=10]="ERR_DISCONNECT",u[u.ERR_ALREADY_OPENED=11]="ERR_ALREADY_OPENED",u[u.ERR_ALREADY_USED=12]="ERR_ALREADY_USED",u[u.ERR_BOX_COUNT_OVER=13]="ERR_BOX_COUNT_OVER",u[u.ERR_BOX_CLIENT_OVER=14]="ERR_BOX_CLIENT_OVER",u[u.ERR_UNSUPPORTED=15]="ERR_UNSUPPORTED",u[u.ERR_DEVICE_BUSY=16]="ERR_DEVICE_BUSY",u[u.ERR_RECOVERY_FAILURE=17]="ERR_RECOVERY_FAILURE",u[u.ERR_FAILURE=255]="ERR_FAILURE",u))(ee||{}),te=(d=>(d[d.SUCCESS=0]="SUCCESS",d[d.ERR_TIMEOUT=1]="ERR_TIMEOUT",d[d.ERR_NOT_FOUND=2]="ERR_NOT_FOUND",d[d.ERR_AUTORECOVER=3]="ERR_AUTORECOVER",d[d.ERR_COVER_OPEN=4]="ERR_COVER_OPEN",d[d.ERR_CUTTER=5]="ERR_CUTTER",d[d.ERR_MECHANICAL=6]="ERR_MECHANICAL",d[d.ERR_EMPTY=7]="ERR_EMPTY",d[d.ERR_UNRECOVERABLE=8]="ERR_UNRECOVERABLE",d[d.ERR_SYSTEM=9]="ERR_SYSTEM",d[d.ERR_PORT=10]="ERR_PORT",d[d.ERR_FAILURE=255]="ERR_FAILURE",d))(te||{}),V=(l=>(l[l.EN=0]="EN",l[l.JA=1]="JA",l[l.ZH_CN=2]="ZH_CN",l[l.ZH_TW=3]="ZH_TW",l[l.KO=4]="KO",l[l.TH=5]="TH",l[l.VI=6]="VI",l[l.MULTI=7]="MULTI",l))(V||{}),re=(o=>(o[o.FONT_A=0]="FONT_A",o[o.FONT_B=1]="FONT_B",o[o.FONT_C=2]="FONT_C",o[o.FONT_D=3]="FONT_D",o[o.FONT_E=4]="FONT_E",o))(re||{}),q=(s=>(s[s.TM_M10=0]="TM_M10",s[s.TM_M30=1]="TM_M30",s[s.TM_P20=2]="TM_P20",s[s.TM_P60=3]="TM_P60",s[s.TM_P60II=4]="TM_P60II",s[s.TM_P80=5]="TM_P80",s[s.TM_T20=6]="TM_T20",s[s.TM_T60=7]="TM_T60",s[s.TM_T70=8]="TM_T70",s[s.TM_T81=9]="TM_T81",s[s.TM_T82=10]="TM_T82",s[s.TM_T83=11]="TM_T83",s[s.TM_T88=12]="TM_T88",s[s.TM_T90=13]="TM_T90",s[s.TM_T90KP=14]="TM_T90KP",s[s.TM_U220=15]="TM_U220",s[s.TM_U330=16]="TM_U330",s[s.TM_L90=17]="TM_L90",s[s.TM_H6000=18]="TM_H6000",s[s.TM_T83III=19]="TM_T83III",s[s.TM_T100=20]="TM_T100",s[s.TM_M30II=21]="TM_M30II",s[s.TM_M50=23]="TM_M50",s[s.TM_T88VII=24]="TM_T88VII",s[s.TM_L90LFC=25]="TM_L90LFC",s[s.TM_L100=26]="TM_L100",s[s.TM_P20II=27]="TM_P20II",s[s.TM_P80II=28]="TM_P80II",s[s.TM_M30III=29]="TM_M30III",s[s.TM_M50II=30]="TM_M50II",s[s.TM_M55=31]="TM_M55",s[s.TM_U220II=32]="TM_U220II",s))(q||{});var p=class t extends h{constructor(r,n,i,o,T){super(n,i,o,T);this.isHardwareError=r;this.name="PrinterError",Object.setPrototypeOf(this,t.prototype)}},z=t=>{if(t instanceof p)return t.isHardwareError;let e=String(t.message||t).toUpperCase();return e.includes("ERR_OFF_LINE")||e.includes("ERR_COVER_OPEN")||e.includes("ERR_PAPER_OUT")||e.includes("ERR_FAILURE")||e.includes("DISCONNECT")||e.includes("PRINT_TIMEOUT")||e.includes("ERROR CODE: 4")||e.includes("ERROR CODE: 7")||e.includes("ERROR CODE: 3")},ne=t=>{if(t instanceof p)return t;let e=f(t),r=z(t);return new p(r,e.code,e.translationCode,e.message,e.originalError)};var M=require("react-native"),m=M.NativeModules.MunchiEpsonModule,G=()=>m?new M.NativeEventEmitter(m):null,_e=t=>new Promise(e=>setTimeout(e,t)),Oe=t=>{if(!t||typeof t!="object")return"";let e=t.code;return typeof e=="string"?e.toUpperCase():""},ye=t=>{if(t instanceof Error)return t.message.toUpperCase();if(t&&typeof t=="object"){let e=t.message;if(typeof e=="string")return e.toUpperCase()}return String(t).toUpperCase()},N=(t,e,r)=>t.includes(r)||e===r||e.includes(r),S=async(t,e=3,r=500)=>{try{return await t()}catch(n){if(e<=1)throw n;let i=ye(n),o=Oe(n);if(N(i,o,"TARGET_IN_USE"))throw n;if(N(i,o,"BUSY")||N(i,o,"IN_USE")||N(i,o,"ERR_IN_USE")||N(i,o,"PRINT_BUSY")||N(i,o,"ERR_CONNECT")||N(i,o,"CONNECT_ERROR")||N(i,o,"ERR_TIMEOUT")||N(i,o,"PRINT_TIMEOUT"))return await _e(r),S(t,e-1,r);throw n}};var ve=new Set([0,3,5,21]),w=class{constructor(e){this.config=e}statusSubscription=null;connectionSubscription=null;connectionCallbacks=new Set;emitStatus(e){for(let r of this.connectionCallbacks)r(e)}ensureStatusListener(){if(this.statusSubscription)return;let e=G();e&&(this.config.logger?.info?.("[EpsonPrinter] Starting status listener for queue management"),this.statusSubscription=e.addListener("onPrinterStatusChange",r=>{if(!this.config.getSessionId()||r.sessionId!==this.config.getSessionId())return;let n=`[EpsonPrinter] Received Status Event: ${r.eventType}`;this.config.logger?.info?.(n),this.config.onEvent({connectionStatus:null,statusEventType:r.eventType,isRecoveryEvent:ve.has(r.eventType)})}))}ensureConnectionListener(){if(this.connectionSubscription)return;let e=G();e&&(this.connectionSubscription=e.addListener("onPrinterConnectionChange",r=>{if(!this.config.getSessionId()||r.sessionId!==this.config.getSessionId())return;let n="UNKNOWN";switch(r.status){case"RECONNECTING":n="RECONNECTING";break;case"RECONNECTED":n="CONNECTED";break;case"DISCONNECTED":n="DISCONNECTED";break;default:n="UNKNOWN"}this.config.onEvent({connectionStatus:n,statusEventType:null,isRecoveryEvent:!1}),this.emitStatus(n)}))}removeStatusListener(){this.statusSubscription&&(this.statusSubscription.remove(),this.statusSubscription=null)}onConnectionChange(e){return this.connectionCallbacks.add(e),e(this.config.getConnectionStatus()),this.ensureConnectionListener(),()=>{this.connectionCallbacks.delete(e),this.connectionCallbacks.size===0&&this.connectionSubscription&&(this.connectionSubscription.remove(),this.connectionSubscription=null)}}};var b=(n=>(n.Small="Small",n.Medium="Medium",n.Large="Large",n))(b||{});var De=(t,e=!1)=>{let r={Small:{normal:{width:1,height:1},item:{width:1,height:1}},Medium:{normal:{width:2,height:2},item:{width:2,height:2}},Large:{normal:{width:2,height:2},item:{width:3,height:3}}},n=e?"item":"normal";return r[t]?.[n]??r.Small.normal},ie=t=>{if(typeof t!="object"||t===null)return null;let e=t;return{target:String(e.target||""),name:String(e.name||""),macAddress:e.macAddress?String(e.macAddress):void 0,ipAddress:e.ipAddress?String(e.ipAddress):void 0,bdAddress:e.bdAddress?String(e.bdAddress):void 0,type:"EPSON"}},se=t=>t.commands.map(e=>{switch(e.type){case"text":return{cmd:"addText",data:e.text,align:e.align,bold:e.bold,underline:e.underline,size:e.size};case"align":return{cmd:"addTextAlign",align:e.align};case"bold":return{cmd:"addTextStyle",bold:e.value};case"fontSize":{let r=De(e.size,e.isItemName);return{cmd:"addTextSize",width:r.width,height:r.height}}case"newline":return{cmd:"addFeedLine",line:e.lines||1};case"separator":return{cmd:"addText",data:`------------------
|
|
2
2
|
`};case"textLang":return{cmd:"addTextLang",lang:e.lang};case"textFont":return{cmd:"addTextFont",font:e.font};case"image":return{cmd:"addImage",data:e.base64,width:e.width};case"cut":return{cmd:"addCut"};case"drawer":return{cmd:"addPulse"};case"barcode":return{cmd:"addBarcode",data:e.data,type:e.system,width:e.width,height:e.height};case"qr":return{cmd:"addSymbol",data:e.data,type:"QRCODE_MODEL_2",level:e.errorCorrection||"M",width:e.size||3};case"feed":return{cmd:"addFeedLine",line:e.lines};default:return null}}).filter(e=>e!==null);var oe=t=>{let e=[];if(t.settings?.fontSize){let r="Medium";t.settings.fontSize==="Small"&&(r="Small"),t.settings.fontSize==="Large"&&(r="Large"),e.push({type:"fontSize",size:r})}t.settings?.fontStyle==="Bold"&&e.push({type:"bold",value:!0}),e.push({type:"align",align:"center"}),t.tbl&&e.push({type:"text",text:`Table: ${t.tbl}
|
|
3
3
|
`,bold:!0,size:"double-height"}),e.push({type:"text",text:`Order: ${t.id}
|
|
4
4
|
`,bold:!0}),e.push({type:"text",text:`${t.ts}
|
|
5
5
|
`}),e.push({type:"text",text:`--------------------------------
|
|
6
|
-
`}),e.push({type:"align",align:"left"});for(let r of t.lines){let n=r.t,i=r.s,o=r.i||0,
|
|
7
|
-
`,align:"center"});continue}e.push({type:"text",text:
|
|
8
|
-
`,align:"center",bold:!0})}else i==="B"?e.push({type:"text",text:
|
|
9
|
-
`,bold:!0}):i==="R"?e.push({type:"text",text:
|
|
10
|
-
`,bold:!0}):e.push({type:"text",text:
|
|
11
|
-
`,align:"left"})}return e.push({type:"feed",lines:3}),e.push({type:"cut"}),{commands:e}};var x=class{constructor(e){this.logger=e}queue=Promise.resolve();isQueuePaused=!1;resumeQueueResolver=null;isPaused(){return this.isQueuePaused}pause(){this.isQueuePaused=!0}resume(){this.isQueuePaused&&(this.isQueuePaused=!1,this.resumeQueueResolver&&(this.resumeQueueResolver(),this.resumeQueueResolver=null))}async waitUntilResumed(){if(this.isQueuePaused)return new Promise(e=>{let r=this.resumeQueueResolver;this.resumeQueueResolver=()=>{r&&r(),e()}})}enqueue(e){return new Promise((r,n)=>{let i=async()=>{this.isQueuePaused&&(this.logger?.info?.("[EpsonPrinter] Queue is PAUSED. Waiting for resume..."),await this.waitUntilResumed(),this.logger?.info?.("[EpsonPrinter] Queue RESUMED."));try{let o=await e();r(o)}catch(o){n(o)}};this.queue=this.queue.then(i,i)})}enqueueBackground(e){this.queue=this.queue.then(e,e)}};var A=class{constructor(e){this.config=e}recoveryTimer=null;start(){this.recoveryTimer||(this.config.logger?.info?.("[EpsonPrinter] Starting recovery polling..."),this.recoveryTimer=setInterval(async()=>{try{let e=await this.config.getStatus();if(e.online&&!e.coverOpen&&e.errorStatus==="NONE")this.config.logger?.info?.("[EpsonPrinter] Poller detected healthy status. Requesting queue resume."),this.config.onRecovered();else{let n=`[EpsonPrinter] Polling... Status: Online=${e.online}, Cover=${e.coverOpen}, Err=${e.errorStatus}`;this.config.logger?.info?.(n)}}catch(e){this.config.logger?.error("[EpsonPrinter] Recovery poll failed",e)}},2e3))}stop(){this.recoveryTimer&&(this.config.logger?.info?.("[EpsonPrinter] Stopping recovery polling."),clearInterval(this.recoveryTimer),this.recoveryTimer=null)}};var L=class{constructor(e){this.logger=e}sessionId=null;sessionInitPromise=null;getSessionId(){return this.sessionId}async ensureSession(){if(!m)throw new Error("Native module not found");return this.sessionId?this.sessionId:this.sessionInitPromise?this.sessionInitPromise:(this.sessionInitPromise=m.initSession().then(e=>(this.sessionId=e,e)).finally(()=>{this.sessionInitPromise=null}),this.sessionInitPromise)}async disposeSession(){if(!m||!this.sessionId){this.sessionId=null;return}let e=this.sessionId;this.sessionId=null;try{await m.disposeSession(e)}catch(r){this.logger?.error("[EpsonPrinter] Dispose session failed",r)}}};var U=class{constructor(e){this.config=e}statusCallbacks=new Set;latestHardwareStatus=null;statusRefreshPromise=null;statusRefreshTimer=null;subscribe(e){return this.statusCallbacks.add(e),this.latestHardwareStatus?e(this.latestHardwareStatus):this.config.getConnectionStatus()!=="CONNECTED"?e(this.config.defaultStatus):this.refreshNow(),()=>{this.statusCallbacks.delete(e)}}handleStatusEvent(){this.scheduleRefresh()}handleConnected(){this.scheduleRefresh(0)}handleDisconnected(){this.clearRefreshTimer(),this.setHardwareStatus(this.config.defaultStatus)}clear(){this.clearRefreshTimer()}async refreshNow(){if(this.config.getConnectionStatus()!=="CONNECTED"){this.setHardwareStatus(this.config.defaultStatus);return}if(this.statusRefreshPromise){await this.statusRefreshPromise;return}this.statusRefreshPromise=(async()=>{try{let e=await this.config.getStatus();this.setHardwareStatus(e)}catch(e){this.config.logger?.error("[EpsonPrinter] Status refresh failed",e),this.latestHardwareStatus||this.setHardwareStatus(this.config.defaultStatus)}})().finally(()=>{this.statusRefreshPromise=null}),await this.statusRefreshPromise}emitHardwareStatus(e){for(let r of this.statusCallbacks)r(e)}setHardwareStatus(e){this.latestHardwareStatus=e,this.emitHardwareStatus(e)}clearRefreshTimer(){this.statusRefreshTimer&&(clearTimeout(this.statusRefreshTimer),this.statusRefreshTimer=null)}scheduleRefresh(e=150){this.config.getConnectionStatus()==="CONNECTED"&&(this.statusRefreshTimer||(this.statusRefreshTimer=setTimeout(()=>{this.statusRefreshTimer=null,this.refreshNow()},e)))}};var Q={online:!1,coverOpen:!1,paperEmpty:!1,paper:"EMPTY",errorStatus:"NONE",drawerOpen:!1},Me=5e3,F=class{disconnectTimer=null;connectionStatus="DISCONNECTED";isConnecting=!1;target=null;defaultTarget;model;lang;logger;sessionManager;queueController;recoveryController;statusController;eventRouter;constructor(e){this.logger=e.logger,this.defaultTarget=e.target??null,this.model=e.model,this.lang=e.lang??0,this.sessionManager=new L(this.logger),this.queueController=new x(this.logger),this.recoveryController=new A({logger:this.logger,getStatus:()=>this.getStatus(),onRecovered:()=>this.resumeQueue()}),this.statusController=new U({logger:this.logger,defaultStatus:Q,getConnectionStatus:()=>this.connectionStatus,getStatus:()=>this.getStatus()}),this.eventRouter=new w({logger:this.logger,getSessionId:()=>this.sessionManager.getSessionId(),getConnectionStatus:()=>this.connectionStatus,onEvent:r=>{r.statusEventType!==null&&(this.statusController.handleStatusEvent(),r.isRecoveryEvent&&this.queueController.isPaused()&&(this.logger?.info?.("[EpsonPrinter] Printer recovered (Event). Resuming queue..."),this.resumeQueue())),r.connectionStatus!==null&&(r.connectionStatus==="CONNECTED"&&(this.connectionStatus="CONNECTED"),r.connectionStatus==="CONNECTED"&&this.statusController.handleConnected(),r.connectionStatus==="DISCONNECTED"&&(this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected()))}})}resumeQueue(){if(!this.queueController.isPaused())return;this.logger?.info?.("[EpsonPrinter] Resuming queue..."),this.recoveryController.stop(),this.queueController.resume()}isIosConnectionRecoveryCandidate(e){return W.Platform.OS!=="ios"?!1:e.code==="CONNECTION_FAILED"||e.code==="TIMEOUT"&&e.translationCode==="printer.error.connection_timeout"||e.translationCode==="printer.error.offline"}hasTargetInUseToken(e){if(!e||typeof e!="object")return!1;let r=String(e.code??"").toUpperCase(),n=String(e.message??"").toUpperCase();return r.includes("TARGET_IN_USE")||n.includes("TARGET_IN_USE")}isIosConnectBusyRecoveryCandidate(e){return W.Platform.OS!=="ios"||e.translationCode!=="printer.error.busy"?!1:!this.hasTargetInUseToken(e.originalError)}async recoverIosSessionForPrint(){if(!m)throw new Error("Native module not found");let e=this.target??this.defaultTarget;if(!e)throw new Error("Printer target is required");let r=this.sessionManager.getSessionId();if(r)try{await m.disconnect(r)}catch(i){this.logger?.error("[EpsonPrinter] iOS recovery disconnect failed (best-effort)",i)}await this.sessionManager.disposeSession(),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED");let n=await this.sessionManager.ensureSession();return await S(()=>m.connect(n,e,Me,this.model,this.lang)),this.target=e,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected(),n}async recoverIosSessionForConnect(e,r){if(!m)throw new Error("Native module not found");let n=this.sessionManager.getSessionId();if(n)try{await m.disconnect(n)}catch(o){this.logger?.error("[EpsonPrinter] iOS connect recovery disconnect failed (best-effort)",o)}await this.sessionManager.disposeSession(),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED");let i=await this.sessionManager.ensureSession();await S(()=>m.connect(i,e,r,this.model,this.lang)),this.target=e,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected()}async connect(e,r=5e3){let n=e??this.defaultTarget;if(!n){let i=new Error("Printer target is required");throw this.logger?.error("[EpsonPrinter] Connect failed: missing target",i),i}return this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),this.queueController.enqueue(async()=>{if(!m){this.logger?.error("[EpsonPrinter] Native module not found");return}if(this.connectionStatus==="CONNECTED"&&this.target===n)return;let i=await this.sessionManager.ensureSession();this.isConnecting=!0,this.connectionStatus="CONNECTING",this.eventRouter.emitStatus("CONNECTING");let o=!1;try{await S(()=>m.connect(i,n,r,this.model,this.lang)),this.target=n,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.isConnecting=!1,this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected()}catch(l){let g=E(l);if(!o&&this.isIosConnectBusyRecoveryCandidate(g)){o=!0,this.logger?.error("[EpsonPrinter] iOS busy connect suspected stale session. Recovering connection and retrying connect once...",g);try{await this.recoverIosSessionForConnect(n,r),this.logger?.info?.("[EpsonPrinter] iOS connect recovery succeeded."),this.isConnecting=!1;return}catch(c){let N=E(c);throw this.logger?.error("[EpsonPrinter] iOS connect recovery failed",N),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.isConnecting=!1,N}}throw this.logger?.error(`[EpsonPrinter] Connect failed for ${n}`,g),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.isConnecting=!1,g}})}async print(e){if(!m)return;this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null);let r=0,n=!1;return this.queueController.enqueue(async()=>{let i=await this.sessionManager.ensureSession(),o=se(e);for(;;){r++,this.logger?.info?.(`[EpsonPrinter] Print attempt ${r}`);try{await S(()=>m.print(i,o));break}catch(l){let g=ne(l);if(!n&&this.isIosConnectionRecoveryCandidate(g)){n=!0,this.logger?.error("[EpsonPrinter] iOS stale session suspected. Recovering connection and retrying print once...",g);try{i=await this.recoverIosSessionForPrint(),this.logger?.info?.("[EpsonPrinter] iOS session recovery succeeded. Retrying print...");continue}catch(c){let N=E(c);throw this.logger?.error("[EpsonPrinter] iOS session recovery failed",N),N}}if(g.isHardwareError){this.queueController.pause(),this.logger?.error(`[EpsonPrinter] Hardware error on attempt ${r}. Waiting for recovery before retry...`,g),this.recoveryController.start(),await this.queueController.waitUntilResumed(),this.logger?.info?.("[EpsonPrinter] Recovery detected. Sending cut to flush partial print before retry...");try{await m.print(i,[{cmd:"addCut"}])}catch{}this.logger?.info?.("[EpsonPrinter] Retrying print job...")}else throw this.logger?.error(`[EpsonPrinter] Print failed (non-recoverable) on attempt ${r}`,g),g}}}).finally(()=>{this.disconnectTimer&&clearTimeout(this.disconnectTimer),this.disconnectTimer=setTimeout(()=>{this.performDisconnect()},5e3)})}performDisconnect(){this.queueController.enqueueBackground(async()=>{if(!this.disconnectTimer)return;let e=this.sessionManager.getSessionId();if(m&&this.connectionStatus==="CONNECTED"&&e)try{await m.disconnect(e),this.connectionStatus="DISCONNECTED",this.target=null,this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),await this.sessionManager.disposeSession()}catch(r){this.logger?.error("[EpsonPrinter] Auto-Disconnect failed",r)}this.disconnectTimer=null})}async printEmbedded(e){try{let r=oe(e);return await this.print(r)}catch(r){let n=E(r);throw String(r).includes("MunchiPrinterError")||this.logger?.error("[EpsonPrinter] Embedded print failed",n),n}}async disconnect(){return this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),this.queueController.enqueue(async()=>{if(!m)return;let e=this.sessionManager.getSessionId();if(e)try{await m.disconnect(e),this.connectionStatus="DISCONNECTED",this.target=null,this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.eventRouter.removeStatusListener(),this.recoveryController.stop()}catch(r){this.logger?.error("[EpsonPrinter] Disconnect failed",r)}finally{this.statusController.clear(),await this.sessionManager.disposeSession()}})}async getStatus(){if(!m)return Q;let e=this.sessionManager.getSessionId();if(!e)return Q;try{return await m.getStatus(e)}catch(r){throw this.logger?.error("[EpsonPrinter] GetStatus failed",r),E(r)}}async openDrawer(){let e={commands:[{type:"drawer"}]};return this.print(e)}onConnectionChange(e){return this.eventRouter.onConnectionChange(e)}onStatusChange(e){return this.statusController.subscribe(e)}};var ue=require("react-native");var ae=ue.NativeModules.MunchiEpsonModule,we={bluetooth:["BT:"],tcp:["TCP:","TCPS:"],usb:["USB:"]},be=t=>t.includes("[local_"),xe=(t,e)=>e?we[e].some(n=>t.startsWith(n)):!0,ce=async t=>{if(!ae)return console.warn("[EpsonDiscovery] Native module not found"),[];try{return(await ae.discover({timeout:t.timeout})).map(ie).filter(r=>!r||be(r.target)?!1:xe(r.target,t.connectionType))}catch(e){let r=E(e);throw console.error("[EpsonDiscovery] Discovery failed",r),r}};var Ae=[[/^TM-m10/i,0],[/^TM-m30III/i,29],[/^TM-m30II/i,21],[/^TM-m30/i,1],[/^TM-m50II/i,30],[/^TM-m50/i,23],[/^TM-m55/i,31],[/^TM-P20II/i,27],[/^TM-P20/i,2],[/^TM-P60II/i,4],[/^TM-P60/i,3],[/^TM-P80II/i,28],[/^TM-P80/i,5],[/^TM-T20/i,6],[/^TM-T60/i,7],[/^TM-T70/i,8],[/^TM-T81/i,9],[/^TM-T82/i,10],[/^TM-T83III/i,19],[/^TM-T83/i,11],[/^TM-T88VII/i,24],[/^TM-T88/i,12],[/^TM-T90KP/i,14],[/^TM-T90/i,13],[/^TM-T100/i,20],[/^TM-U220II/i,32],[/^TM-U220/i,15],[/^TM-U330/i,16],[/^TM-L90LFC/i,25],[/^TM-L90/i,17],[/^TM-L100/i,26],[/^TM-H6000/i,18]],le=t=>{for(let[e,r]of Ae)if(e.test(t))return r;return null};var de=t=>{let e=E(t),r=e.message.toUpperCase(),n=t instanceof p?t.isHardwareError:z(t),i=e.translationCode==="printer.error.busy"||r.includes("BUSY")||r.includes("IN_USE")||r.includes("PRINT_BUSY"),o=e.code==="TIMEOUT"||e.translationCode==="printer.error.connection_timeout"||r.includes("TIMEOUT"),l=e.code==="CONNECTION_FAILED"||e.translationCode==="printer.error.offline",g=e.code==="DISCOVERY_FAILED",c="UNKNOWN";return n?c="HARDWARE":i?c="BUSY":o?c="TIMEOUT":l?c="CONNECTION":g?c="DISCOVERY":e.code==="PRINT_FAILED"&&(c="PRINT"),{code:e.code,translationCode:e.translationCode,message:e.message,category:c,isHardwareError:n,retryable:i||o,shouldPauseQueue:n,raw:t}},Le=t=>de(t);var me=Pe(require("react")),R=require("react");var ge=(0,R.createContext)(void 0),Ue=({config:t,logger:e,children:r})=>{let[n,i]=(0,R.useState)();(0,R.useEffect)(()=>{e&&B(e)},[e]);let o=(0,R.useMemo)(()=>{let g={...t,logger:e??t.logger};return K(g)},[t.lang,t.model,t.target,e]),l=(0,R.useMemo)(()=>({printer:o,config:t,isReady:!0,error:n}),[o,t,n]);return me.default.createElement(ge.Provider,{value:l},r)},k=()=>{let t=(0,R.useContext)(ge);if(!t)throw new Error("usePrinter must be used within a PrinterProvider");return t};var f=require("react");function Fe(t={}){let{enabled:e=!0}=t,{printer:r,config:n}=k(),[i,o]=(0,f.useState)("DISCONNECTED"),[l,g]=(0,f.useState)(null),[c,N]=(0,f.useState)(null),X=(0,f.useRef)("DISCONNECTED"),$=(0,f.useRef)(null),d=c!==null,I=(0,f.useCallback)(C=>{$.current=C,N(C)},[]),_=(0,f.useCallback)(C=>{if(C instanceof Error&&C.message){I(C.message);return}if(typeof C=="string"&&C.length>0){I(C);return}I("Unknown printer error")},[I]),a=(0,f.useCallback)(()=>{$.current!==null&&I(null)},[I]);return(0,f.useEffect)(()=>r.onConnectionChange(O=>{X.current=O,o(O),O==="CONNECTED"&&a()}),[a,r]),(0,f.useEffect)(()=>e?r.onStatusChange(O=>{g(O),a()}):void 0,[a,e,r]),(0,f.useEffect)(()=>{e&&i==="CONNECTED"&&r.getStatus().then(C=>{g(C),a()}).catch(_)},[_,a,i,e,r]),(0,f.useEffect)(()=>{let C=X.current;if(e){C==="DISCONNECTED"&&i==="DISCONNECTED"&&r.connect(n.target,5e3).then(a).catch(_);return}(i==="CONNECTED"||i==="CONNECTING")&&r.disconnect().then(a).catch(_)},[_,a,n.target,i,e,r]),{connectionStatus:i,hardwareStatus:l,isError:d,errorMessage:c}}var Te="1.0.5";function K(t){return new F({...t,logger:t.logger??Y()})}0&&(module.exports={Epos2CallbackCode,Epos2ConnectionEvent,Epos2ErrorStatus,Epos2Font,Epos2Lang,Epos2StatusEvent,EpsonModel,FontSize,MunchiPrinterError,PrinterError,PrinterErrorCode,PrinterProvider,PrinterTranslationCode,VERSION,discoverPrinters,getGlobalLogger,getPrinter,resolveEpsonError,resolveModelFromBluetoothName,resolvePrinterError,setGlobalLogger,usePrinter,usePrinterStatus});
|
|
6
|
+
`}),e.push({type:"align",align:"left"});for(let r of t.lines){let n=r.t,i=r.s,o=r.i||0,c=`${" ".repeat(o)}${n}`;if(i==="C"){if(n.includes("---")){e.push({type:"text",text:`--------------------------------
|
|
7
|
+
`,align:"center"});continue}e.push({type:"text",text:c+`
|
|
8
|
+
`,align:"center",bold:!0})}else i==="B"?e.push({type:"text",text:c+`
|
|
9
|
+
`,bold:!0}):i==="R"?e.push({type:"text",text:c+`
|
|
10
|
+
`,bold:!0}):e.push({type:"text",text:c+`
|
|
11
|
+
`,align:"left"})}return e.push({type:"feed",lines:3}),e.push({type:"cut"}),{commands:e}};var x=class{constructor(e){this.logger=e}queue=Promise.resolve();isQueuePaused=!1;resumeQueueResolver=null;isPaused(){return this.isQueuePaused}pause(){this.isQueuePaused=!0}resume(){this.isQueuePaused&&(this.isQueuePaused=!1,this.resumeQueueResolver&&(this.resumeQueueResolver(),this.resumeQueueResolver=null))}async waitUntilResumed(){if(this.isQueuePaused)return new Promise(e=>{let r=this.resumeQueueResolver;this.resumeQueueResolver=()=>{r&&r(),e()}})}enqueue(e){return new Promise((r,n)=>{let i=async()=>{this.isQueuePaused&&(this.logger?.info?.("[EpsonPrinter] Queue is PAUSED. Waiting for resume..."),await this.waitUntilResumed(),this.logger?.info?.("[EpsonPrinter] Queue RESUMED."));try{let o=await e();r(o)}catch(o){n(o)}};this.queue=this.queue.then(i,i)})}enqueueBackground(e){this.queue=this.queue.then(e,e)}};var A=class{constructor(e){this.config=e}recoveryTimer=null;start(){this.recoveryTimer||(this.config.logger?.info?.("[EpsonPrinter] Starting recovery polling..."),this.recoveryTimer=setInterval(async()=>{try{let e=await this.config.getStatus();if(e.online&&!e.coverOpen&&e.errorStatus==="NONE")this.config.logger?.info?.("[EpsonPrinter] Poller detected healthy status. Requesting queue resume."),this.config.onRecovered();else{let n=`[EpsonPrinter] Polling... Status: Online=${e.online}, Cover=${e.coverOpen}, Err=${e.errorStatus}`;this.config.logger?.info?.(n)}}catch(e){this.config.logger?.error("[EpsonPrinter] Recovery poll failed",e)}},2e3))}stop(){this.recoveryTimer&&(this.config.logger?.info?.("[EpsonPrinter] Stopping recovery polling."),clearInterval(this.recoveryTimer),this.recoveryTimer=null)}};var L=class{constructor(e){this.logger=e}sessionId=null;sessionInitPromise=null;getSessionId(){return this.sessionId}async ensureSession(){if(!m)throw new Error("Native module not found");return this.sessionId?this.sessionId:this.sessionInitPromise?this.sessionInitPromise:(this.sessionInitPromise=m.initSession().then(e=>(this.sessionId=e,e)).finally(()=>{this.sessionInitPromise=null}),this.sessionInitPromise)}async disposeSession(){if(!m||!this.sessionId){this.sessionId=null;return}let e=this.sessionId;this.sessionId=null;try{await m.disposeSession(e)}catch(r){this.logger?.error("[EpsonPrinter] Dispose session failed",r)}}};var U=class{constructor(e){this.config=e}statusCallbacks=new Set;latestHardwareStatus=null;statusRefreshPromise=null;statusRefreshTimer=null;subscribe(e){return this.statusCallbacks.add(e),this.latestHardwareStatus?e(this.latestHardwareStatus):this.config.getConnectionStatus()!=="CONNECTED"?e(this.config.defaultStatus):this.refreshNow(),()=>{this.statusCallbacks.delete(e)}}handleStatusEvent(){this.scheduleRefresh()}handleConnected(){this.scheduleRefresh(0)}handleDisconnected(){this.clearRefreshTimer(),this.setHardwareStatus(this.config.defaultStatus)}clear(){this.clearRefreshTimer()}async refreshNow(){if(this.config.getConnectionStatus()!=="CONNECTED"){this.setHardwareStatus(this.config.defaultStatus);return}if(this.statusRefreshPromise){await this.statusRefreshPromise;return}this.statusRefreshPromise=(async()=>{try{let e=await this.config.getStatus();this.setHardwareStatus(e)}catch(e){this.config.logger?.error("[EpsonPrinter] Status refresh failed",e),this.latestHardwareStatus||this.setHardwareStatus(this.config.defaultStatus)}})().finally(()=>{this.statusRefreshPromise=null}),await this.statusRefreshPromise}emitHardwareStatus(e){for(let r of this.statusCallbacks)r(e)}setHardwareStatus(e){this.latestHardwareStatus=e,this.emitHardwareStatus(e)}clearRefreshTimer(){this.statusRefreshTimer&&(clearTimeout(this.statusRefreshTimer),this.statusRefreshTimer=null)}scheduleRefresh(e=150){this.config.getConnectionStatus()==="CONNECTED"&&(this.statusRefreshTimer||(this.statusRefreshTimer=setTimeout(()=>{this.statusRefreshTimer=null,this.refreshNow()},e)))}};var Q={online:!1,coverOpen:!1,paperEmpty:!1,paper:"EMPTY",errorStatus:"NONE",drawerOpen:!1},Me=5e3,F=class{disconnectTimer=null;connectionStatus="DISCONNECTED";isConnecting=!1;target=null;defaultTarget;model;lang;logger;sessionManager;queueController;recoveryController;statusController;eventRouter;constructor(e){this.logger=e.logger,this.defaultTarget=e.target??null,this.model=e.model,this.lang=e.lang??0,this.sessionManager=new L(this.logger),this.queueController=new x(this.logger),this.recoveryController=new A({logger:this.logger,getStatus:()=>this.getStatus(),onRecovered:()=>this.resumeQueue()}),this.statusController=new U({logger:this.logger,defaultStatus:Q,getConnectionStatus:()=>this.connectionStatus,getStatus:()=>this.getStatus()}),this.eventRouter=new w({logger:this.logger,getSessionId:()=>this.sessionManager.getSessionId(),getConnectionStatus:()=>this.connectionStatus,onEvent:r=>{r.statusEventType!==null&&(this.statusController.handleStatusEvent(),r.isRecoveryEvent&&this.queueController.isPaused()&&(this.logger?.info?.("[EpsonPrinter] Printer recovered (Event). Resuming queue..."),this.resumeQueue())),r.connectionStatus!==null&&(r.connectionStatus==="CONNECTED"&&(this.connectionStatus="CONNECTED"),r.connectionStatus==="CONNECTED"&&this.statusController.handleConnected(),r.connectionStatus==="DISCONNECTED"&&(this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected()))}})}resumeQueue(){if(!this.queueController.isPaused())return;this.logger?.info?.("[EpsonPrinter] Resuming queue..."),this.recoveryController.stop(),this.queueController.resume()}isIosConnectionRecoveryCandidate(e){return W.Platform.OS!=="ios"?!1:e.code==="CONNECTION_FAILED"||e.code==="TIMEOUT"&&e.translationCode==="printer.error.connection_timeout"||e.translationCode==="printer.error.offline"}hasTargetInUseToken(e){if(!e||typeof e!="object")return!1;let r=String(e.code??"").toUpperCase(),n=String(e.message??"").toUpperCase();return r.includes("TARGET_IN_USE")||n.includes("TARGET_IN_USE")}isIosConnectBusyRecoveryCandidate(e){return W.Platform.OS!=="ios"||e.translationCode!=="printer.error.busy"?!1:!this.hasTargetInUseToken(e.originalError)}async recoverIosSessionForPrint(){if(!m)throw new Error("Native module not found");let e=this.target??this.defaultTarget;if(!e)throw new Error("Printer target is required");let r=this.sessionManager.getSessionId();if(r)try{await m.disconnect(r)}catch(i){this.logger?.error("[EpsonPrinter] iOS recovery disconnect failed (best-effort)",i)}await this.sessionManager.disposeSession(),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED");let n=await this.sessionManager.ensureSession();return await S(()=>m.connect(n,e,Me,this.model,this.lang)),this.target=e,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected(),n}async recoverIosSessionForConnect(e,r){if(!m)throw new Error("Native module not found");let n=this.sessionManager.getSessionId();if(n)try{await m.disconnect(n)}catch(o){this.logger?.error("[EpsonPrinter] iOS connect recovery disconnect failed (best-effort)",o)}await this.sessionManager.disposeSession(),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED");let i=await this.sessionManager.ensureSession();await S(()=>m.connect(i,e,r,this.model,this.lang)),this.target=e,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected()}async connect(e,r=5e3){let n=e??this.defaultTarget;if(!n){let i=new Error("Printer target is required");throw this.logger?.error("[EpsonPrinter] Connect failed: missing target",i),i}return this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),this.queueController.enqueue(async()=>{if(!m){this.logger?.error("[EpsonPrinter] Native module not found");return}if(this.connectionStatus==="CONNECTED"&&this.target===n)return;let i=await this.sessionManager.ensureSession();this.isConnecting=!0,this.connectionStatus="CONNECTING",this.eventRouter.emitStatus("CONNECTING");let o=!1;try{await S(()=>m.connect(i,n,r,this.model,this.lang)),this.target=n,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.isConnecting=!1,this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected()}catch(T){let c=f(T);if(!o&&this.isIosConnectBusyRecoveryCandidate(c)){o=!0,this.logger?.error("[EpsonPrinter] iOS busy connect suspected stale session. Recovering connection and retrying connect once...",c);try{await this.recoverIosSessionForConnect(n,r),this.logger?.info?.("[EpsonPrinter] iOS connect recovery succeeded."),this.isConnecting=!1;return}catch(l){let P=f(l);throw this.logger?.error("[EpsonPrinter] iOS connect recovery failed",P),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.isConnecting=!1,P}}throw this.logger?.error(`[EpsonPrinter] Connect failed for ${n}`,c),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.isConnecting=!1,c}})}async print(e){if(!m)return;this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null);let r=0,n=!1;return this.queueController.enqueue(async()=>{let i=await this.sessionManager.ensureSession(),o=se(e);for(;;){r++,this.logger?.info?.(`[EpsonPrinter] Print attempt ${r}`);try{await S(()=>m.print(i,o));break}catch(T){let c=ne(T);if(!n&&this.isIosConnectionRecoveryCandidate(c)){n=!0,this.logger?.error("[EpsonPrinter] iOS stale session suspected. Recovering connection and retrying print once...",c);try{i=await this.recoverIosSessionForPrint(),this.logger?.info?.("[EpsonPrinter] iOS session recovery succeeded. Retrying print...");continue}catch(l){let P=f(l);throw this.logger?.error("[EpsonPrinter] iOS session recovery failed",P),P}}if(c.isHardwareError){this.queueController.pause(),this.logger?.error(`[EpsonPrinter] Hardware error on attempt ${r}. Waiting for recovery before retry...`,c),this.recoveryController.start(),await this.queueController.waitUntilResumed(),this.logger?.info?.("[EpsonPrinter] Recovery detected. Sending cut to flush partial print before retry...");try{await m.print(i,[{cmd:"addCut"}])}catch{}this.logger?.info?.("[EpsonPrinter] Retrying print job...")}else throw this.logger?.error(`[EpsonPrinter] Print failed (non-recoverable) on attempt ${r}`,c),c}}}).finally(()=>{this.disconnectTimer&&clearTimeout(this.disconnectTimer),this.disconnectTimer=setTimeout(()=>{this.performDisconnect()},5e3)})}performDisconnect(){this.queueController.enqueueBackground(async()=>{if(!this.disconnectTimer)return;let e=this.sessionManager.getSessionId();if(m&&this.connectionStatus==="CONNECTED"&&e)try{await m.disconnect(e),this.connectionStatus="DISCONNECTED",this.target=null,this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),await this.sessionManager.disposeSession()}catch(r){this.logger?.error("[EpsonPrinter] Auto-Disconnect failed",r)}this.disconnectTimer=null})}async printEmbedded(e){try{let r=oe(e);return await this.print(r)}catch(r){let n=f(r);throw String(r).includes("MunchiPrinterError")||this.logger?.error("[EpsonPrinter] Embedded print failed",n),n}}async disconnect(){return this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),this.queueController.enqueue(async()=>{if(!m)return;let e=this.sessionManager.getSessionId();if(e)try{await m.disconnect(e),this.connectionStatus="DISCONNECTED",this.target=null,this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.eventRouter.removeStatusListener(),this.recoveryController.stop()}catch(r){this.logger?.error("[EpsonPrinter] Disconnect failed",r)}finally{this.statusController.clear(),await this.sessionManager.disposeSession()}})}async getStatus(){if(!m)return Q;let e=this.sessionManager.getSessionId();if(!e)return Q;try{return await m.getStatus(e)}catch(r){throw this.logger?.error("[EpsonPrinter] GetStatus failed",r),f(r)}}async openDrawer(){let e={commands:[{type:"drawer"}]};return this.print(e)}onConnectionChange(e){return this.eventRouter.onConnectionChange(e)}onStatusChange(e){return this.statusController.subscribe(e)}};var ue=require("react-native");var ae=ue.NativeModules.MunchiEpsonModule,we={bluetooth:["BT:"],tcp:["TCP:","TCPS:"],usb:["USB:"]},be=t=>t.includes("[local_"),xe=(t,e)=>e?we[e].some(n=>t.startsWith(n)):!0,ce=async t=>{if(!ae)return console.warn("[EpsonDiscovery] Native module not found"),[];try{return(await ae.discover({timeout:t.timeout})).map(ie).filter(r=>!r||be(r.target)?!1:xe(r.target,t.connectionType))}catch(e){let r=f(e);throw console.error("[EpsonDiscovery] Discovery failed",r),r}};var Ae=[[/^TM-m10/i,0],[/^TM-m30III/i,29],[/^TM-m30II/i,21],[/^TM-m30/i,1],[/^TM-m50II/i,30],[/^TM-m50/i,23],[/^TM-m55/i,31],[/^TM-P20II/i,27],[/^TM-P20/i,2],[/^TM-P60II/i,4],[/^TM-P60/i,3],[/^TM-P80II/i,28],[/^TM-P80/i,5],[/^TM-T20/i,6],[/^TM-T60/i,7],[/^TM-T70/i,8],[/^TM-T81/i,9],[/^TM-T82/i,10],[/^TM-T83III/i,19],[/^TM-T83/i,11],[/^TM-T88VII/i,24],[/^TM-T88/i,12],[/^TM-T90KP/i,14],[/^TM-T90/i,13],[/^TM-T100/i,20],[/^TM-U220II/i,32],[/^TM-U220/i,15],[/^TM-U330/i,16],[/^TM-L90LFC/i,25],[/^TM-L90/i,17],[/^TM-L100/i,26],[/^TM-H6000/i,18]],le=t=>{for(let[e,r]of Ae)if(e.test(t))return r;return null};var de=t=>{let e=f(t),r=e.message.toUpperCase(),n=t instanceof p?t.isHardwareError:z(t),i=e.translationCode==="printer.error.busy"||r.includes("BUSY")||r.includes("IN_USE")||r.includes("PRINT_BUSY"),o=e.code==="TIMEOUT"||e.translationCode==="printer.error.connection_timeout"||r.includes("TIMEOUT"),T=e.code==="CONNECTION_FAILED"||e.translationCode==="printer.error.offline",c=e.code==="DISCOVERY_FAILED",l="UNKNOWN";return n?l="HARDWARE":i?l="BUSY":o?l="TIMEOUT":T?l="CONNECTION":c?l="DISCOVERY":e.code==="PRINT_FAILED"&&(l="PRINT"),{code:e.code,translationCode:e.translationCode,message:e.message,category:l,isHardwareError:n,retryable:i||o,shouldPauseQueue:n,raw:t}},Le=t=>de(t);var me=Ne(require("react")),R=require("react");var ge=(0,R.createContext)(void 0),Ue=({config:t,logger:e,children:r})=>{let[n,i]=(0,R.useState)();(0,R.useEffect)(()=>{e&&B(e)},[e]);let o=(0,R.useMemo)(()=>{let c={...t,logger:e??t.logger};return K(c)},[t.lang,t.model,t.target,e]),T=(0,R.useMemo)(()=>({printer:o,config:t,isReady:!0,error:n}),[o,t,n]);return me.default.createElement(ge.Provider,{value:T},r)},k=()=>{let t=(0,R.useContext)(ge);if(!t)throw new Error("usePrinter must be used within a PrinterProvider");return t};var E=require("react");function Fe(t={}){let{enabled:e=!0}=t,{printer:r,config:n}=k(),[i,o]=(0,E.useState)("DISCONNECTED"),[T,c]=(0,E.useState)(null),[l,P]=(0,E.useState)(null),X=(0,E.useRef)("DISCONNECTED"),$=(0,E.useRef)(null),d=l!==null,I=(0,E.useCallback)(C=>{$.current=C,P(C)},[]),_=(0,E.useCallback)(C=>{if(C instanceof Error&&C.message){I(C.message);return}if(typeof C=="string"&&C.length>0){I(C);return}I("Unknown printer error")},[I]),a=(0,E.useCallback)(()=>{$.current!==null&&I(null)},[I]);return(0,E.useEffect)(()=>r.onConnectionChange(O=>{X.current=O,o(O),O==="CONNECTED"&&a()}),[a,r]),(0,E.useEffect)(()=>e?r.onStatusChange(O=>{c(O),a()}):void 0,[a,e,r]),(0,E.useEffect)(()=>{e&&i==="CONNECTED"&&r.getStatus().then(C=>{c(C),a()}).catch(_)},[_,a,i,e,r]),(0,E.useEffect)(()=>{let C=X.current;if(e){C==="DISCONNECTED"&&i==="DISCONNECTED"&&r.connect(n.target,5e3).then(a).catch(_);return}(i==="CONNECTED"||i==="CONNECTING")&&r.disconnect().then(a).catch(_)},[_,a,n.target,i,e,r]),{connectionStatus:i,hardwareStatus:T,isError:d,errorMessage:l}}var Te="1.0.7";function K(t){return new F({...t,logger:t.logger??Y()})}0&&(module.exports={Epos2CallbackCode,Epos2ConnectionEvent,Epos2ErrorStatus,Epos2Font,Epos2Lang,Epos2StatusEvent,EpsonModel,FontSize,MunchiPrinterError,PrinterError,PrinterErrorCode,PrinterProvider,PrinterTranslationCode,VERSION,discoverPrinters,getGlobalLogger,getPrinter,resolveEpsonError,resolveModelFromBluetoothName,resolvePrinterError,setGlobalLogger,usePrinter,usePrinterStatus});
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var q={},z=t=>{q.logger=t},G=()=>q.logger;import{Platform as j}from"react-native";var _=(
|
|
1
|
+
var q={},z=t=>{q.logger=t},G=()=>q.logger;import{Platform as j}from"react-native";var _=(T=>(T.CONNECTION_FAILED="CONNECTION_FAILED",T.PRINT_FAILED="PRINT_FAILED",T.DISCOVERY_FAILED="DISCOVERY_FAILED",T.TIMEOUT="TIMEOUT",T.NATIVE_MODULE_MISSING="NATIVE_MODULE_MISSING",T.UNKNOWN="UNKNOWN",T))(_||{}),O=(c=>(c.ERR_PRINTER_RECONNECT_REQUIRED="printer.error.reconnect_required",c.ERR_PRINTER_OFFLINE="printer.error.offline",c.ERR_PRINTER_BUSY="printer.error.busy",c.ERR_PRINTER_COVER_OPEN="printer.error.cover_open",c.ERR_PRINTER_PAPER_EMPTY="printer.error.paper_empty",c.ERR_CONNECTION_TIMEOUT="printer.error.connection_timeout",c.ERR_UNKNOWN="printer.error.unknown",c))(O||{}),h=class t extends Error{constructor(r,n,i,o){super(i);this.code=r;this.translationCode=n;this.originalError=o;this.name="MunchiPrinterError",Object.setPrototypeOf(this,t.prototype)}};var se=t=>{if(!t||typeof t!="object")return"";let e=t.code;return typeof e=="string"?e:""},oe=t=>{if(t instanceof Error)return t.message;if(t&&typeof t=="object"){let e=t.message;if(typeof e=="string")return e}return String(t)},g=(t,e,r)=>t.includes(r)||e===r||e.includes(r),C=t=>{if(t instanceof h)return t;let e=oe(t),r=se(t),n=e.toUpperCase(),i=r.toUpperCase();return n.includes("ERROR CODE: 4")?new h("PRINT_FAILED","printer.error.cover_open","Printer cover is open",t):n.includes("ERROR CODE: 3")?new h("PRINT_FAILED","printer.error.busy","Printer is performing auto-recovery",t):n.includes("ERROR CODE: 7")?new h("PRINT_FAILED","printer.error.paper_empty","Printer paper is empty",t):g(n,i,"TARGET_IN_USE")||g(n,i,"BUSY")||g(n,i,"IN_USE")||g(n,i,"PRINT_BUSY")||g(n,i,"DISCOVERY_BUSY")?new h("TIMEOUT","printer.error.busy","Printer is busy",t):g(n,i,"TIMEOUT")||g(n,i,"ERR_TIMEOUT")||g(n,i,"PRINT_TIMEOUT")?new h("TIMEOUT","printer.error.connection_timeout","Operation timed out",t):g(n,i,"PRINTER_RECONNECT_REQUIRED")||n.includes("RECONNECT THE PRINTER")?new h("CONNECTION_FAILED","printer.error.reconnect_required",e,t):g(n,i,"PERMISSION_DENIED")||g(n,i,"LOCATION_DISABLED")||g(n,i,"BLUETOOTH_DISABLED")?new h("CONNECTION_FAILED","printer.error.offline",e,t):g(n,i,"DISCOVERY_ERROR")||n.includes("DISCOVERY")?new h("DISCOVERY_FAILED","printer.error.unknown",e,t):g(n,i,"PRINTER_OFFLINE")||g(n,i,"SESSION_ERROR")||g(n,i,"STATUS_ERROR")||g(n,i,"INIT_ERROR")||g(n,i,"PRINT_CANCELED")||g(n,i,"DISCONNECT")||g(n,i,"ERR_DISCONNECT")||n.includes("PRINTER NOT CONNECTED")||n.includes("OFFLINE")?new h("CONNECTION_FAILED","printer.error.offline",n.includes("OFFLINE")?e:"Printer disconnected",t):g(n,i,"CONNECT_ERROR")||n.includes("FAILED TO CONNECT")||g(n,i,"ERR_CONNECT")?new h("CONNECTION_FAILED","printer.error.offline","Failed to connect to printer",t):g(n,i,"PRINT_ERROR")||g(n,i,"PRINT_FAILURE")?new h("PRINT_FAILED","printer.error.unknown",e,t):new h("UNKNOWN","printer.error.unknown",e,t)};var Q=(a=>(a[a.ONLINE=0]="ONLINE",a[a.OFFLINE=1]="OFFLINE",a[a.POWER_OFF=2]="POWER_OFF",a[a.COVER_CLOSE=3]="COVER_CLOSE",a[a.COVER_OPEN=4]="COVER_OPEN",a[a.PAPER_OK=5]="PAPER_OK",a[a.PAPER_NEAR_END=6]="PAPER_NEAR_END",a[a.PAPER_EMPTY=7]="PAPER_EMPTY",a[a.DRAWER_HIGH=8]="DRAWER_HIGH",a[a.DRAWER_LOW=9]="DRAWER_LOW",a[a.BATTERY_ENOUGH=10]="BATTERY_ENOUGH",a[a.BATTERY_EMPTY=11]="BATTERY_EMPTY",a[a.AUTO_RECOVER_ERROR=20]="AUTO_RECOVER_ERROR",a[a.AUTO_RECOVER_OK=21]="AUTO_RECOVER_OK",a[a.UNRECOVERABLE_ERROR=22]="UNRECOVERABLE_ERROR",a))(Q||{}),ae=(n=>(n[n.RECONNECTING=0]="RECONNECTING",n[n.RECONNECT=1]="RECONNECT",n[n.DISCONNECT=2]="DISCONNECT",n))(ae||{}),ue=(u=>(u[u.SUCCESS=0]="SUCCESS",u[u.ERR_PARAM=1]="ERR_PARAM",u[u.ERR_CONNECT=2]="ERR_CONNECT",u[u.ERR_TIMEOUT=3]="ERR_TIMEOUT",u[u.ERR_MEMORY=4]="ERR_MEMORY",u[u.ERR_ILLEGAL=5]="ERR_ILLEGAL",u[u.ERR_PROCESSING=6]="ERR_PROCESSING",u[u.ERR_NOT_FOUND=7]="ERR_NOT_FOUND",u[u.ERR_IN_USE=8]="ERR_IN_USE",u[u.ERR_TYPE_INVALID=9]="ERR_TYPE_INVALID",u[u.ERR_DISCONNECT=10]="ERR_DISCONNECT",u[u.ERR_ALREADY_OPENED=11]="ERR_ALREADY_OPENED",u[u.ERR_ALREADY_USED=12]="ERR_ALREADY_USED",u[u.ERR_BOX_COUNT_OVER=13]="ERR_BOX_COUNT_OVER",u[u.ERR_BOX_CLIENT_OVER=14]="ERR_BOX_CLIENT_OVER",u[u.ERR_UNSUPPORTED=15]="ERR_UNSUPPORTED",u[u.ERR_DEVICE_BUSY=16]="ERR_DEVICE_BUSY",u[u.ERR_RECOVERY_FAILURE=17]="ERR_RECOVERY_FAILURE",u[u.ERR_FAILURE=255]="ERR_FAILURE",u))(ue||{}),ce=(d=>(d[d.SUCCESS=0]="SUCCESS",d[d.ERR_TIMEOUT=1]="ERR_TIMEOUT",d[d.ERR_NOT_FOUND=2]="ERR_NOT_FOUND",d[d.ERR_AUTORECOVER=3]="ERR_AUTORECOVER",d[d.ERR_COVER_OPEN=4]="ERR_COVER_OPEN",d[d.ERR_CUTTER=5]="ERR_CUTTER",d[d.ERR_MECHANICAL=6]="ERR_MECHANICAL",d[d.ERR_EMPTY=7]="ERR_EMPTY",d[d.ERR_UNRECOVERABLE=8]="ERR_UNRECOVERABLE",d[d.ERR_SYSTEM=9]="ERR_SYSTEM",d[d.ERR_PORT=10]="ERR_PORT",d[d.ERR_FAILURE=255]="ERR_FAILURE",d))(ce||{}),W=(l=>(l[l.EN=0]="EN",l[l.JA=1]="JA",l[l.ZH_CN=2]="ZH_CN",l[l.ZH_TW=3]="ZH_TW",l[l.KO=4]="KO",l[l.TH=5]="TH",l[l.VI=6]="VI",l[l.MULTI=7]="MULTI",l))(W||{}),le=(o=>(o[o.FONT_A=0]="FONT_A",o[o.FONT_B=1]="FONT_B",o[o.FONT_C=2]="FONT_C",o[o.FONT_D=3]="FONT_D",o[o.FONT_E=4]="FONT_E",o))(le||{}),k=(s=>(s[s.TM_M10=0]="TM_M10",s[s.TM_M30=1]="TM_M30",s[s.TM_P20=2]="TM_P20",s[s.TM_P60=3]="TM_P60",s[s.TM_P60II=4]="TM_P60II",s[s.TM_P80=5]="TM_P80",s[s.TM_T20=6]="TM_T20",s[s.TM_T60=7]="TM_T60",s[s.TM_T70=8]="TM_T70",s[s.TM_T81=9]="TM_T81",s[s.TM_T82=10]="TM_T82",s[s.TM_T83=11]="TM_T83",s[s.TM_T88=12]="TM_T88",s[s.TM_T90=13]="TM_T90",s[s.TM_T90KP=14]="TM_T90KP",s[s.TM_U220=15]="TM_U220",s[s.TM_U330=16]="TM_U330",s[s.TM_L90=17]="TM_L90",s[s.TM_H6000=18]="TM_H6000",s[s.TM_T83III=19]="TM_T83III",s[s.TM_T100=20]="TM_T100",s[s.TM_M30II=21]="TM_M30II",s[s.TM_M50=23]="TM_M50",s[s.TM_T88VII=24]="TM_T88VII",s[s.TM_L90LFC=25]="TM_L90LFC",s[s.TM_L100=26]="TM_L100",s[s.TM_P20II=27]="TM_P20II",s[s.TM_P80II=28]="TM_P80II",s[s.TM_M30III=29]="TM_M30III",s[s.TM_M50II=30]="TM_M50II",s[s.TM_M55=31]="TM_M55",s[s.TM_U220II=32]="TM_U220II",s))(k||{});var R=class t extends h{constructor(r,n,i,o,T){super(n,i,o,T);this.isHardwareError=r;this.name="PrinterError",Object.setPrototypeOf(this,t.prototype)}},A=t=>{if(t instanceof R)return t.isHardwareError;let e=String(t.message||t).toUpperCase();return e.includes("ERR_OFF_LINE")||e.includes("ERR_COVER_OPEN")||e.includes("ERR_PAPER_OUT")||e.includes("ERR_FAILURE")||e.includes("DISCONNECT")||e.includes("PRINT_TIMEOUT")||e.includes("ERROR CODE: 4")||e.includes("ERROR CODE: 7")||e.includes("ERROR CODE: 3")},K=t=>{if(t instanceof R)return t;let e=C(t),r=A(t);return new R(r,e.code,e.translationCode,e.message,e.originalError)};import{NativeEventEmitter as de,NativeModules as me}from"react-native";var m=me.MunchiEpsonModule,L=()=>m?new de(m):null,ge=t=>new Promise(e=>setTimeout(e,t)),Te=t=>{if(!t||typeof t!="object")return"";let e=t.code;return typeof e=="string"?e.toUpperCase():""},he=t=>{if(t instanceof Error)return t.message.toUpperCase();if(t&&typeof t=="object"){let e=t.message;if(typeof e=="string")return e.toUpperCase()}return String(t).toUpperCase()},f=(t,e,r)=>t.includes(r)||e===r||e.includes(r),P=async(t,e=3,r=500)=>{try{return await t()}catch(n){if(e<=1)throw n;let i=he(n),o=Te(n);if(f(i,o,"TARGET_IN_USE"))throw n;if(f(i,o,"BUSY")||f(i,o,"IN_USE")||f(i,o,"ERR_IN_USE")||f(i,o,"PRINT_BUSY")||f(i,o,"ERR_CONNECT")||f(i,o,"CONNECT_ERROR")||f(i,o,"ERR_TIMEOUT")||f(i,o,"PRINT_TIMEOUT"))return await ge(r),P(t,e-1,r);throw n}};var Ee=new Set([0,3,5,21]),y=class{constructor(e){this.config=e}statusSubscription=null;connectionSubscription=null;connectionCallbacks=new Set;emitStatus(e){for(let r of this.connectionCallbacks)r(e)}ensureStatusListener(){if(this.statusSubscription)return;let e=L();e&&(this.config.logger?.info?.("[EpsonPrinter] Starting status listener for queue management"),this.statusSubscription=e.addListener("onPrinterStatusChange",r=>{if(!this.config.getSessionId()||r.sessionId!==this.config.getSessionId())return;let n=`[EpsonPrinter] Received Status Event: ${r.eventType}`;this.config.logger?.info?.(n),this.config.onEvent({connectionStatus:null,statusEventType:r.eventType,isRecoveryEvent:Ee.has(r.eventType)})}))}ensureConnectionListener(){if(this.connectionSubscription)return;let e=L();e&&(this.connectionSubscription=e.addListener("onPrinterConnectionChange",r=>{if(!this.config.getSessionId()||r.sessionId!==this.config.getSessionId())return;let n="UNKNOWN";switch(r.status){case"RECONNECTING":n="RECONNECTING";break;case"RECONNECTED":n="CONNECTED";break;case"DISCONNECTED":n="DISCONNECTED";break;default:n="UNKNOWN"}this.config.onEvent({connectionStatus:n,statusEventType:null,isRecoveryEvent:!1}),this.emitStatus(n)}))}removeStatusListener(){this.statusSubscription&&(this.statusSubscription.remove(),this.statusSubscription=null)}onConnectionChange(e){return this.connectionCallbacks.add(e),e(this.config.getConnectionStatus()),this.ensureConnectionListener(),()=>{this.connectionCallbacks.delete(e),this.connectionCallbacks.size===0&&this.connectionSubscription&&(this.connectionSubscription.remove(),this.connectionSubscription=null)}}};var U=(n=>(n.Small="Small",n.Medium="Medium",n.Large="Large",n))(U||{});var Ce=(t,e=!1)=>{let r={Small:{normal:{width:1,height:1},item:{width:1,height:1}},Medium:{normal:{width:2,height:2},item:{width:2,height:2}},Large:{normal:{width:2,height:2},item:{width:3,height:3}}},n=e?"item":"normal";return r[t]?.[n]??r.Small.normal},X=t=>{if(typeof t!="object"||t===null)return null;let e=t;return{target:String(e.target||""),name:String(e.name||""),macAddress:e.macAddress?String(e.macAddress):void 0,ipAddress:e.ipAddress?String(e.ipAddress):void 0,bdAddress:e.bdAddress?String(e.bdAddress):void 0,type:"EPSON"}},$=t=>t.commands.map(e=>{switch(e.type){case"text":return{cmd:"addText",data:e.text,align:e.align,bold:e.bold,underline:e.underline,size:e.size};case"align":return{cmd:"addTextAlign",align:e.align};case"bold":return{cmd:"addTextStyle",bold:e.value};case"fontSize":{let r=Ce(e.size,e.isItemName);return{cmd:"addTextSize",width:r.width,height:r.height}}case"newline":return{cmd:"addFeedLine",line:e.lines||1};case"separator":return{cmd:"addText",data:`------------------
|
|
2
2
|
`};case"textLang":return{cmd:"addTextLang",lang:e.lang};case"textFont":return{cmd:"addTextFont",font:e.font};case"image":return{cmd:"addImage",data:e.base64,width:e.width};case"cut":return{cmd:"addCut"};case"drawer":return{cmd:"addPulse"};case"barcode":return{cmd:"addBarcode",data:e.data,type:e.system,width:e.width,height:e.height};case"qr":return{cmd:"addSymbol",data:e.data,type:"QRCODE_MODEL_2",level:e.errorCorrection||"M",width:e.size||3};case"feed":return{cmd:"addFeedLine",line:e.lines};default:return null}}).filter(e=>e!==null);var J=t=>{let e=[];if(t.settings?.fontSize){let r="Medium";t.settings.fontSize==="Small"&&(r="Small"),t.settings.fontSize==="Large"&&(r="Large"),e.push({type:"fontSize",size:r})}t.settings?.fontStyle==="Bold"&&e.push({type:"bold",value:!0}),e.push({type:"align",align:"center"}),t.tbl&&e.push({type:"text",text:`Table: ${t.tbl}
|
|
3
3
|
`,bold:!0,size:"double-height"}),e.push({type:"text",text:`Order: ${t.id}
|
|
4
4
|
`,bold:!0}),e.push({type:"text",text:`${t.ts}
|
|
5
5
|
`}),e.push({type:"text",text:`--------------------------------
|
|
6
|
-
`}),e.push({type:"align",align:"left"});for(let r of t.lines){let n=r.t,i=r.s,o=r.i||0,
|
|
7
|
-
`,align:"center"});continue}e.push({type:"text",text:
|
|
8
|
-
`,align:"center",bold:!0})}else i==="B"?e.push({type:"text",text:
|
|
9
|
-
`,bold:!0}):i==="R"?e.push({type:"text",text:
|
|
10
|
-
`,bold:!0}):e.push({type:"text",text:
|
|
11
|
-
`,align:"left"})}return e.push({type:"feed",lines:3}),e.push({type:"cut"}),{commands:e}};var v=class{constructor(e){this.logger=e}queue=Promise.resolve();isQueuePaused=!1;resumeQueueResolver=null;isPaused(){return this.isQueuePaused}pause(){this.isQueuePaused=!0}resume(){this.isQueuePaused&&(this.isQueuePaused=!1,this.resumeQueueResolver&&(this.resumeQueueResolver(),this.resumeQueueResolver=null))}async waitUntilResumed(){if(this.isQueuePaused)return new Promise(e=>{let r=this.resumeQueueResolver;this.resumeQueueResolver=()=>{r&&r(),e()}})}enqueue(e){return new Promise((r,n)=>{let i=async()=>{this.isQueuePaused&&(this.logger?.info?.("[EpsonPrinter] Queue is PAUSED. Waiting for resume..."),await this.waitUntilResumed(),this.logger?.info?.("[EpsonPrinter] Queue RESUMED."));try{let o=await e();r(o)}catch(o){n(o)}};this.queue=this.queue.then(i,i)})}enqueueBackground(e){this.queue=this.queue.then(e,e)}};var D=class{constructor(e){this.config=e}recoveryTimer=null;start(){this.recoveryTimer||(this.config.logger?.info?.("[EpsonPrinter] Starting recovery polling..."),this.recoveryTimer=setInterval(async()=>{try{let e=await this.config.getStatus();if(e.online&&!e.coverOpen&&e.errorStatus==="NONE")this.config.logger?.info?.("[EpsonPrinter] Poller detected healthy status. Requesting queue resume."),this.config.onRecovered();else{let n=`[EpsonPrinter] Polling... Status: Online=${e.online}, Cover=${e.coverOpen}, Err=${e.errorStatus}`;this.config.logger?.info?.(n)}}catch(e){this.config.logger?.error("[EpsonPrinter] Recovery poll failed",e)}},2e3))}stop(){this.recoveryTimer&&(this.config.logger?.info?.("[EpsonPrinter] Stopping recovery polling."),clearInterval(this.recoveryTimer),this.recoveryTimer=null)}};var M=class{constructor(e){this.logger=e}sessionId=null;sessionInitPromise=null;getSessionId(){return this.sessionId}async ensureSession(){if(!m)throw new Error("Native module not found");return this.sessionId?this.sessionId:this.sessionInitPromise?this.sessionInitPromise:(this.sessionInitPromise=m.initSession().then(e=>(this.sessionId=e,e)).finally(()=>{this.sessionInitPromise=null}),this.sessionInitPromise)}async disposeSession(){if(!m||!this.sessionId){this.sessionId=null;return}let e=this.sessionId;this.sessionId=null;try{await m.disposeSession(e)}catch(r){this.logger?.error("[EpsonPrinter] Dispose session failed",r)}}};var w=class{constructor(e){this.config=e}statusCallbacks=new Set;latestHardwareStatus=null;statusRefreshPromise=null;statusRefreshTimer=null;subscribe(e){return this.statusCallbacks.add(e),this.latestHardwareStatus?e(this.latestHardwareStatus):this.config.getConnectionStatus()!=="CONNECTED"?e(this.config.defaultStatus):this.refreshNow(),()=>{this.statusCallbacks.delete(e)}}handleStatusEvent(){this.scheduleRefresh()}handleConnected(){this.scheduleRefresh(0)}handleDisconnected(){this.clearRefreshTimer(),this.setHardwareStatus(this.config.defaultStatus)}clear(){this.clearRefreshTimer()}async refreshNow(){if(this.config.getConnectionStatus()!=="CONNECTED"){this.setHardwareStatus(this.config.defaultStatus);return}if(this.statusRefreshPromise){await this.statusRefreshPromise;return}this.statusRefreshPromise=(async()=>{try{let e=await this.config.getStatus();this.setHardwareStatus(e)}catch(e){this.config.logger?.error("[EpsonPrinter] Status refresh failed",e),this.latestHardwareStatus||this.setHardwareStatus(this.config.defaultStatus)}})().finally(()=>{this.statusRefreshPromise=null}),await this.statusRefreshPromise}emitHardwareStatus(e){for(let r of this.statusCallbacks)r(e)}setHardwareStatus(e){this.latestHardwareStatus=e,this.emitHardwareStatus(e)}clearRefreshTimer(){this.statusRefreshTimer&&(clearTimeout(this.statusRefreshTimer),this.statusRefreshTimer=null)}scheduleRefresh(e=150){this.config.getConnectionStatus()==="CONNECTED"&&(this.statusRefreshTimer||(this.statusRefreshTimer=setTimeout(()=>{this.statusRefreshTimer=null,this.refreshNow()},e)))}};var F={online:!1,coverOpen:!1,paperEmpty:!1,paper:"EMPTY",errorStatus:"NONE",drawerOpen:!1},Ee=5e3,b=class{disconnectTimer=null;connectionStatus="DISCONNECTED";isConnecting=!1;target=null;defaultTarget;model;lang;logger;sessionManager;queueController;recoveryController;statusController;eventRouter;constructor(e){this.logger=e.logger,this.defaultTarget=e.target??null,this.model=e.model,this.lang=e.lang??0,this.sessionManager=new M(this.logger),this.queueController=new v(this.logger),this.recoveryController=new D({logger:this.logger,getStatus:()=>this.getStatus(),onRecovered:()=>this.resumeQueue()}),this.statusController=new w({logger:this.logger,defaultStatus:F,getConnectionStatus:()=>this.connectionStatus,getStatus:()=>this.getStatus()}),this.eventRouter=new y({logger:this.logger,getSessionId:()=>this.sessionManager.getSessionId(),getConnectionStatus:()=>this.connectionStatus,onEvent:r=>{r.statusEventType!==null&&(this.statusController.handleStatusEvent(),r.isRecoveryEvent&&this.queueController.isPaused()&&(this.logger?.info?.("[EpsonPrinter] Printer recovered (Event). Resuming queue..."),this.resumeQueue())),r.connectionStatus!==null&&(r.connectionStatus==="CONNECTED"&&(this.connectionStatus="CONNECTED"),r.connectionStatus==="CONNECTED"&&this.statusController.handleConnected(),r.connectionStatus==="DISCONNECTED"&&(this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected()))}})}resumeQueue(){if(!this.queueController.isPaused())return;this.logger?.info?.("[EpsonPrinter] Resuming queue..."),this.recoveryController.stop(),this.queueController.resume()}isIosConnectionRecoveryCandidate(e){return j.OS!=="ios"?!1:e.code==="CONNECTION_FAILED"||e.code==="TIMEOUT"&&e.translationCode==="printer.error.connection_timeout"||e.translationCode==="printer.error.offline"}hasTargetInUseToken(e){if(!e||typeof e!="object")return!1;let r=String(e.code??"").toUpperCase(),n=String(e.message??"").toUpperCase();return r.includes("TARGET_IN_USE")||n.includes("TARGET_IN_USE")}isIosConnectBusyRecoveryCandidate(e){return j.OS!=="ios"||e.translationCode!=="printer.error.busy"?!1:!this.hasTargetInUseToken(e.originalError)}async recoverIosSessionForPrint(){if(!m)throw new Error("Native module not found");let e=this.target??this.defaultTarget;if(!e)throw new Error("Printer target is required");let r=this.sessionManager.getSessionId();if(r)try{await m.disconnect(r)}catch(i){this.logger?.error("[EpsonPrinter] iOS recovery disconnect failed (best-effort)",i)}await this.sessionManager.disposeSession(),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED");let n=await this.sessionManager.ensureSession();return await N(()=>m.connect(n,e,Ee,this.model,this.lang)),this.target=e,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected(),n}async recoverIosSessionForConnect(e,r){if(!m)throw new Error("Native module not found");let n=this.sessionManager.getSessionId();if(n)try{await m.disconnect(n)}catch(o){this.logger?.error("[EpsonPrinter] iOS connect recovery disconnect failed (best-effort)",o)}await this.sessionManager.disposeSession(),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED");let i=await this.sessionManager.ensureSession();await N(()=>m.connect(i,e,r,this.model,this.lang)),this.target=e,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected()}async connect(e,r=5e3){let n=e??this.defaultTarget;if(!n){let i=new Error("Printer target is required");throw this.logger?.error("[EpsonPrinter] Connect failed: missing target",i),i}return this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),this.queueController.enqueue(async()=>{if(!m){this.logger?.error("[EpsonPrinter] Native module not found");return}if(this.connectionStatus==="CONNECTED"&&this.target===n)return;let i=await this.sessionManager.ensureSession();this.isConnecting=!0,this.connectionStatus="CONNECTING",this.eventRouter.emitStatus("CONNECTING");let o=!1;try{await N(()=>m.connect(i,n,r,this.model,this.lang)),this.target=n,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.isConnecting=!1,this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected()}catch(l){let g=C(l);if(!o&&this.isIosConnectBusyRecoveryCandidate(g)){o=!0,this.logger?.error("[EpsonPrinter] iOS busy connect suspected stale session. Recovering connection and retrying connect once...",g);try{await this.recoverIosSessionForConnect(n,r),this.logger?.info?.("[EpsonPrinter] iOS connect recovery succeeded."),this.isConnecting=!1;return}catch(c){let p=C(c);throw this.logger?.error("[EpsonPrinter] iOS connect recovery failed",p),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.isConnecting=!1,p}}throw this.logger?.error(`[EpsonPrinter] Connect failed for ${n}`,g),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.isConnecting=!1,g}})}async print(e){if(!m)return;this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null);let r=0,n=!1;return this.queueController.enqueue(async()=>{let i=await this.sessionManager.ensureSession(),o=$(e);for(;;){r++,this.logger?.info?.(`[EpsonPrinter] Print attempt ${r}`);try{await N(()=>m.print(i,o));break}catch(l){let g=K(l);if(!n&&this.isIosConnectionRecoveryCandidate(g)){n=!0,this.logger?.error("[EpsonPrinter] iOS stale session suspected. Recovering connection and retrying print once...",g);try{i=await this.recoverIosSessionForPrint(),this.logger?.info?.("[EpsonPrinter] iOS session recovery succeeded. Retrying print...");continue}catch(c){let p=C(c);throw this.logger?.error("[EpsonPrinter] iOS session recovery failed",p),p}}if(g.isHardwareError){this.queueController.pause(),this.logger?.error(`[EpsonPrinter] Hardware error on attempt ${r}. Waiting for recovery before retry...`,g),this.recoveryController.start(),await this.queueController.waitUntilResumed(),this.logger?.info?.("[EpsonPrinter] Recovery detected. Sending cut to flush partial print before retry...");try{await m.print(i,[{cmd:"addCut"}])}catch{}this.logger?.info?.("[EpsonPrinter] Retrying print job...")}else throw this.logger?.error(`[EpsonPrinter] Print failed (non-recoverable) on attempt ${r}`,g),g}}}).finally(()=>{this.disconnectTimer&&clearTimeout(this.disconnectTimer),this.disconnectTimer=setTimeout(()=>{this.performDisconnect()},5e3)})}performDisconnect(){this.queueController.enqueueBackground(async()=>{if(!this.disconnectTimer)return;let e=this.sessionManager.getSessionId();if(m&&this.connectionStatus==="CONNECTED"&&e)try{await m.disconnect(e),this.connectionStatus="DISCONNECTED",this.target=null,this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),await this.sessionManager.disposeSession()}catch(r){this.logger?.error("[EpsonPrinter] Auto-Disconnect failed",r)}this.disconnectTimer=null})}async printEmbedded(e){try{let r=J(e);return await this.print(r)}catch(r){let n=C(r);throw String(r).includes("MunchiPrinterError")||this.logger?.error("[EpsonPrinter] Embedded print failed",n),n}}async disconnect(){return this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),this.queueController.enqueue(async()=>{if(!m)return;let e=this.sessionManager.getSessionId();if(e)try{await m.disconnect(e),this.connectionStatus="DISCONNECTED",this.target=null,this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.eventRouter.removeStatusListener(),this.recoveryController.stop()}catch(r){this.logger?.error("[EpsonPrinter] Disconnect failed",r)}finally{this.statusController.clear(),await this.sessionManager.disposeSession()}})}async getStatus(){if(!m)return F;let e=this.sessionManager.getSessionId();if(!e)return F;try{return await m.getStatus(e)}catch(r){throw this.logger?.error("[EpsonPrinter] GetStatus failed",r),C(r)}}async openDrawer(){let e={commands:[{type:"drawer"}]};return this.print(e)}onConnectionChange(e){return this.eventRouter.onConnectionChange(e)}onStatusChange(e){return this.statusController.subscribe(e)}};import{NativeModules as Re}from"react-native";var Z=Re.MunchiEpsonModule,pe={bluetooth:["BT:"],tcp:["TCP:","TCPS:"],usb:["USB:"]},Pe=t=>t.includes("[local_"),Ne=(t,e)=>e?pe[e].some(n=>t.startsWith(n)):!0,Ie=async t=>{if(!Z)return console.warn("[EpsonDiscovery] Native module not found"),[];try{return(await Z.discover({timeout:t.timeout})).map(X).filter(r=>!r||Pe(r.target)?!1:Ne(r.target,t.connectionType))}catch(e){let r=C(e);throw console.error("[EpsonDiscovery] Discovery failed",r),r}};var Se=[[/^TM-m10/i,0],[/^TM-m30III/i,29],[/^TM-m30II/i,21],[/^TM-m30/i,1],[/^TM-m50II/i,30],[/^TM-m50/i,23],[/^TM-m55/i,31],[/^TM-P20II/i,27],[/^TM-P20/i,2],[/^TM-P60II/i,4],[/^TM-P60/i,3],[/^TM-P80II/i,28],[/^TM-P80/i,5],[/^TM-T20/i,6],[/^TM-T60/i,7],[/^TM-T70/i,8],[/^TM-T81/i,9],[/^TM-T82/i,10],[/^TM-T83III/i,19],[/^TM-T83/i,11],[/^TM-T88VII/i,24],[/^TM-T88/i,12],[/^TM-T90KP/i,14],[/^TM-T90/i,13],[/^TM-T100/i,20],[/^TM-U220II/i,32],[/^TM-U220/i,15],[/^TM-U330/i,16],[/^TM-L90LFC/i,25],[/^TM-L90/i,17],[/^TM-L100/i,26],[/^TM-H6000/i,18]],_e=t=>{for(let[e,r]of Se)if(e.test(t))return r;return null};var Oe=t=>{let e=C(t),r=e.message.toUpperCase(),n=t instanceof R?t.isHardwareError:A(t),i=e.translationCode==="printer.error.busy"||r.includes("BUSY")||r.includes("IN_USE")||r.includes("PRINT_BUSY"),o=e.code==="TIMEOUT"||e.translationCode==="printer.error.connection_timeout"||r.includes("TIMEOUT"),l=e.code==="CONNECTION_FAILED"||e.translationCode==="printer.error.offline",g=e.code==="DISCOVERY_FAILED",c="UNKNOWN";return n?c="HARDWARE":i?c="BUSY":o?c="TIMEOUT":l?c="CONNECTION":g?c="DISCOVERY":e.code==="PRINT_FAILED"&&(c="PRINT"),{code:e.code,translationCode:e.translationCode,message:e.message,category:c,isHardwareError:n,retryable:i||o,shouldPauseQueue:n,raw:t}},Ot=t=>Oe(t);import ye from"react";import{createContext as ve,useContext as De,useEffect as Me,useMemo as ee,useState as we}from"react";var te=ve(void 0),bt=({config:t,logger:e,children:r})=>{let[n,i]=we();Me(()=>{e&&z(e)},[e]);let o=ee(()=>{let g={...t,logger:e??t.logger};return ne(g)},[t.lang,t.model,t.target,e]),l=ee(()=>({printer:o,config:t,isReady:!0,error:n}),[o,t,n]);return ye.createElement(te.Provider,{value:l},r)},re=()=>{let t=De(te);if(!t)throw new Error("usePrinter must be used within a PrinterProvider");return t};import{useCallback as B,useEffect as x,useRef as ie,useState as Y}from"react";function Ut(t={}){let{enabled:e=!0}=t,{printer:r,config:n}=re(),[i,o]=Y("DISCONNECTED"),[l,g]=Y(null),[c,p]=Y(null),H=ie("DISCONNECTED"),V=ie(null),d=c!==null,P=B(f=>{V.current=f,p(f)},[]),I=B(f=>{if(f instanceof Error&&f.message){P(f.message);return}if(typeof f=="string"&&f.length>0){P(f);return}P("Unknown printer error")},[P]),a=B(()=>{V.current!==null&&P(null)},[P]);return x(()=>r.onConnectionChange(S=>{H.current=S,o(S),S==="CONNECTED"&&a()}),[a,r]),x(()=>e?r.onStatusChange(S=>{g(S),a()}):void 0,[a,e,r]),x(()=>{e&&i==="CONNECTED"&&r.getStatus().then(f=>{g(f),a()}).catch(I)},[I,a,i,e,r]),x(()=>{let f=H.current;if(e){f==="DISCONNECTED"&&i==="DISCONNECTED"&&r.connect(n.target,5e3).then(a).catch(I);return}(i==="CONNECTED"||i==="CONNECTING")&&r.disconnect().then(a).catch(I)},[I,a,n.target,i,e,r]),{connectionStatus:i,hardwareStatus:l,isError:d,errorMessage:c}}var be="1.0.5";function ne(t){return new b({...t,logger:t.logger??G()})}export{ce as Epos2CallbackCode,ae as Epos2ConnectionEvent,ue as Epos2ErrorStatus,le as Epos2Font,W as Epos2Lang,Q as Epos2StatusEvent,k as EpsonModel,U as FontSize,h as MunchiPrinterError,R as PrinterError,_ as PrinterErrorCode,bt as PrinterProvider,O as PrinterTranslationCode,be as VERSION,Ie as discoverPrinters,G as getGlobalLogger,ne as getPrinter,Ot as resolveEpsonError,_e as resolveModelFromBluetoothName,Oe as resolvePrinterError,z as setGlobalLogger,re as usePrinter,Ut as usePrinterStatus};
|
|
6
|
+
`}),e.push({type:"align",align:"left"});for(let r of t.lines){let n=r.t,i=r.s,o=r.i||0,c=`${" ".repeat(o)}${n}`;if(i==="C"){if(n.includes("---")){e.push({type:"text",text:`--------------------------------
|
|
7
|
+
`,align:"center"});continue}e.push({type:"text",text:c+`
|
|
8
|
+
`,align:"center",bold:!0})}else i==="B"?e.push({type:"text",text:c+`
|
|
9
|
+
`,bold:!0}):i==="R"?e.push({type:"text",text:c+`
|
|
10
|
+
`,bold:!0}):e.push({type:"text",text:c+`
|
|
11
|
+
`,align:"left"})}return e.push({type:"feed",lines:3}),e.push({type:"cut"}),{commands:e}};var v=class{constructor(e){this.logger=e}queue=Promise.resolve();isQueuePaused=!1;resumeQueueResolver=null;isPaused(){return this.isQueuePaused}pause(){this.isQueuePaused=!0}resume(){this.isQueuePaused&&(this.isQueuePaused=!1,this.resumeQueueResolver&&(this.resumeQueueResolver(),this.resumeQueueResolver=null))}async waitUntilResumed(){if(this.isQueuePaused)return new Promise(e=>{let r=this.resumeQueueResolver;this.resumeQueueResolver=()=>{r&&r(),e()}})}enqueue(e){return new Promise((r,n)=>{let i=async()=>{this.isQueuePaused&&(this.logger?.info?.("[EpsonPrinter] Queue is PAUSED. Waiting for resume..."),await this.waitUntilResumed(),this.logger?.info?.("[EpsonPrinter] Queue RESUMED."));try{let o=await e();r(o)}catch(o){n(o)}};this.queue=this.queue.then(i,i)})}enqueueBackground(e){this.queue=this.queue.then(e,e)}};var D=class{constructor(e){this.config=e}recoveryTimer=null;start(){this.recoveryTimer||(this.config.logger?.info?.("[EpsonPrinter] Starting recovery polling..."),this.recoveryTimer=setInterval(async()=>{try{let e=await this.config.getStatus();if(e.online&&!e.coverOpen&&e.errorStatus==="NONE")this.config.logger?.info?.("[EpsonPrinter] Poller detected healthy status. Requesting queue resume."),this.config.onRecovered();else{let n=`[EpsonPrinter] Polling... Status: Online=${e.online}, Cover=${e.coverOpen}, Err=${e.errorStatus}`;this.config.logger?.info?.(n)}}catch(e){this.config.logger?.error("[EpsonPrinter] Recovery poll failed",e)}},2e3))}stop(){this.recoveryTimer&&(this.config.logger?.info?.("[EpsonPrinter] Stopping recovery polling."),clearInterval(this.recoveryTimer),this.recoveryTimer=null)}};var M=class{constructor(e){this.logger=e}sessionId=null;sessionInitPromise=null;getSessionId(){return this.sessionId}async ensureSession(){if(!m)throw new Error("Native module not found");return this.sessionId?this.sessionId:this.sessionInitPromise?this.sessionInitPromise:(this.sessionInitPromise=m.initSession().then(e=>(this.sessionId=e,e)).finally(()=>{this.sessionInitPromise=null}),this.sessionInitPromise)}async disposeSession(){if(!m||!this.sessionId){this.sessionId=null;return}let e=this.sessionId;this.sessionId=null;try{await m.disposeSession(e)}catch(r){this.logger?.error("[EpsonPrinter] Dispose session failed",r)}}};var w=class{constructor(e){this.config=e}statusCallbacks=new Set;latestHardwareStatus=null;statusRefreshPromise=null;statusRefreshTimer=null;subscribe(e){return this.statusCallbacks.add(e),this.latestHardwareStatus?e(this.latestHardwareStatus):this.config.getConnectionStatus()!=="CONNECTED"?e(this.config.defaultStatus):this.refreshNow(),()=>{this.statusCallbacks.delete(e)}}handleStatusEvent(){this.scheduleRefresh()}handleConnected(){this.scheduleRefresh(0)}handleDisconnected(){this.clearRefreshTimer(),this.setHardwareStatus(this.config.defaultStatus)}clear(){this.clearRefreshTimer()}async refreshNow(){if(this.config.getConnectionStatus()!=="CONNECTED"){this.setHardwareStatus(this.config.defaultStatus);return}if(this.statusRefreshPromise){await this.statusRefreshPromise;return}this.statusRefreshPromise=(async()=>{try{let e=await this.config.getStatus();this.setHardwareStatus(e)}catch(e){this.config.logger?.error("[EpsonPrinter] Status refresh failed",e),this.latestHardwareStatus||this.setHardwareStatus(this.config.defaultStatus)}})().finally(()=>{this.statusRefreshPromise=null}),await this.statusRefreshPromise}emitHardwareStatus(e){for(let r of this.statusCallbacks)r(e)}setHardwareStatus(e){this.latestHardwareStatus=e,this.emitHardwareStatus(e)}clearRefreshTimer(){this.statusRefreshTimer&&(clearTimeout(this.statusRefreshTimer),this.statusRefreshTimer=null)}scheduleRefresh(e=150){this.config.getConnectionStatus()==="CONNECTED"&&(this.statusRefreshTimer||(this.statusRefreshTimer=setTimeout(()=>{this.statusRefreshTimer=null,this.refreshNow()},e)))}};var F={online:!1,coverOpen:!1,paperEmpty:!1,paper:"EMPTY",errorStatus:"NONE",drawerOpen:!1},fe=5e3,b=class{disconnectTimer=null;connectionStatus="DISCONNECTED";isConnecting=!1;target=null;defaultTarget;model;lang;logger;sessionManager;queueController;recoveryController;statusController;eventRouter;constructor(e){this.logger=e.logger,this.defaultTarget=e.target??null,this.model=e.model,this.lang=e.lang??0,this.sessionManager=new M(this.logger),this.queueController=new v(this.logger),this.recoveryController=new D({logger:this.logger,getStatus:()=>this.getStatus(),onRecovered:()=>this.resumeQueue()}),this.statusController=new w({logger:this.logger,defaultStatus:F,getConnectionStatus:()=>this.connectionStatus,getStatus:()=>this.getStatus()}),this.eventRouter=new y({logger:this.logger,getSessionId:()=>this.sessionManager.getSessionId(),getConnectionStatus:()=>this.connectionStatus,onEvent:r=>{r.statusEventType!==null&&(this.statusController.handleStatusEvent(),r.isRecoveryEvent&&this.queueController.isPaused()&&(this.logger?.info?.("[EpsonPrinter] Printer recovered (Event). Resuming queue..."),this.resumeQueue())),r.connectionStatus!==null&&(r.connectionStatus==="CONNECTED"&&(this.connectionStatus="CONNECTED"),r.connectionStatus==="CONNECTED"&&this.statusController.handleConnected(),r.connectionStatus==="DISCONNECTED"&&(this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected()))}})}resumeQueue(){if(!this.queueController.isPaused())return;this.logger?.info?.("[EpsonPrinter] Resuming queue..."),this.recoveryController.stop(),this.queueController.resume()}isIosConnectionRecoveryCandidate(e){return j.OS!=="ios"?!1:e.code==="CONNECTION_FAILED"||e.code==="TIMEOUT"&&e.translationCode==="printer.error.connection_timeout"||e.translationCode==="printer.error.offline"}hasTargetInUseToken(e){if(!e||typeof e!="object")return!1;let r=String(e.code??"").toUpperCase(),n=String(e.message??"").toUpperCase();return r.includes("TARGET_IN_USE")||n.includes("TARGET_IN_USE")}isIosConnectBusyRecoveryCandidate(e){return j.OS!=="ios"||e.translationCode!=="printer.error.busy"?!1:!this.hasTargetInUseToken(e.originalError)}async recoverIosSessionForPrint(){if(!m)throw new Error("Native module not found");let e=this.target??this.defaultTarget;if(!e)throw new Error("Printer target is required");let r=this.sessionManager.getSessionId();if(r)try{await m.disconnect(r)}catch(i){this.logger?.error("[EpsonPrinter] iOS recovery disconnect failed (best-effort)",i)}await this.sessionManager.disposeSession(),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED");let n=await this.sessionManager.ensureSession();return await P(()=>m.connect(n,e,fe,this.model,this.lang)),this.target=e,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected(),n}async recoverIosSessionForConnect(e,r){if(!m)throw new Error("Native module not found");let n=this.sessionManager.getSessionId();if(n)try{await m.disconnect(n)}catch(o){this.logger?.error("[EpsonPrinter] iOS connect recovery disconnect failed (best-effort)",o)}await this.sessionManager.disposeSession(),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED");let i=await this.sessionManager.ensureSession();await P(()=>m.connect(i,e,r,this.model,this.lang)),this.target=e,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected()}async connect(e,r=5e3){let n=e??this.defaultTarget;if(!n){let i=new Error("Printer target is required");throw this.logger?.error("[EpsonPrinter] Connect failed: missing target",i),i}return this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),this.queueController.enqueue(async()=>{if(!m){this.logger?.error("[EpsonPrinter] Native module not found");return}if(this.connectionStatus==="CONNECTED"&&this.target===n)return;let i=await this.sessionManager.ensureSession();this.isConnecting=!0,this.connectionStatus="CONNECTING",this.eventRouter.emitStatus("CONNECTING");let o=!1;try{await P(()=>m.connect(i,n,r,this.model,this.lang)),this.target=n,this.connectionStatus="CONNECTED",this.eventRouter.emitStatus("CONNECTED"),this.isConnecting=!1,this.eventRouter.ensureStatusListener(),this.eventRouter.ensureConnectionListener(),this.statusController.handleConnected()}catch(T){let c=C(T);if(!o&&this.isIosConnectBusyRecoveryCandidate(c)){o=!0,this.logger?.error("[EpsonPrinter] iOS busy connect suspected stale session. Recovering connection and retrying connect once...",c);try{await this.recoverIosSessionForConnect(n,r),this.logger?.info?.("[EpsonPrinter] iOS connect recovery succeeded."),this.isConnecting=!1;return}catch(l){let p=C(l);throw this.logger?.error("[EpsonPrinter] iOS connect recovery failed",p),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.isConnecting=!1,p}}throw this.logger?.error(`[EpsonPrinter] Connect failed for ${n}`,c),this.connectionStatus="DISCONNECTED",this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.isConnecting=!1,c}})}async print(e){if(!m)return;this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null);let r=0,n=!1;return this.queueController.enqueue(async()=>{let i=await this.sessionManager.ensureSession(),o=$(e);for(;;){r++,this.logger?.info?.(`[EpsonPrinter] Print attempt ${r}`);try{await P(()=>m.print(i,o));break}catch(T){let c=K(T);if(!n&&this.isIosConnectionRecoveryCandidate(c)){n=!0,this.logger?.error("[EpsonPrinter] iOS stale session suspected. Recovering connection and retrying print once...",c);try{i=await this.recoverIosSessionForPrint(),this.logger?.info?.("[EpsonPrinter] iOS session recovery succeeded. Retrying print...");continue}catch(l){let p=C(l);throw this.logger?.error("[EpsonPrinter] iOS session recovery failed",p),p}}if(c.isHardwareError){this.queueController.pause(),this.logger?.error(`[EpsonPrinter] Hardware error on attempt ${r}. Waiting for recovery before retry...`,c),this.recoveryController.start(),await this.queueController.waitUntilResumed(),this.logger?.info?.("[EpsonPrinter] Recovery detected. Sending cut to flush partial print before retry...");try{await m.print(i,[{cmd:"addCut"}])}catch{}this.logger?.info?.("[EpsonPrinter] Retrying print job...")}else throw this.logger?.error(`[EpsonPrinter] Print failed (non-recoverable) on attempt ${r}`,c),c}}}).finally(()=>{this.disconnectTimer&&clearTimeout(this.disconnectTimer),this.disconnectTimer=setTimeout(()=>{this.performDisconnect()},5e3)})}performDisconnect(){this.queueController.enqueueBackground(async()=>{if(!this.disconnectTimer)return;let e=this.sessionManager.getSessionId();if(m&&this.connectionStatus==="CONNECTED"&&e)try{await m.disconnect(e),this.connectionStatus="DISCONNECTED",this.target=null,this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),await this.sessionManager.disposeSession()}catch(r){this.logger?.error("[EpsonPrinter] Auto-Disconnect failed",r)}this.disconnectTimer=null})}async printEmbedded(e){try{let r=J(e);return await this.print(r)}catch(r){let n=C(r);throw String(r).includes("MunchiPrinterError")||this.logger?.error("[EpsonPrinter] Embedded print failed",n),n}}async disconnect(){return this.disconnectTimer&&(clearTimeout(this.disconnectTimer),this.disconnectTimer=null),this.queueController.enqueue(async()=>{if(!m)return;let e=this.sessionManager.getSessionId();if(e)try{await m.disconnect(e),this.connectionStatus="DISCONNECTED",this.target=null,this.statusController.handleDisconnected(),this.eventRouter.emitStatus("DISCONNECTED"),this.eventRouter.removeStatusListener(),this.recoveryController.stop()}catch(r){this.logger?.error("[EpsonPrinter] Disconnect failed",r)}finally{this.statusController.clear(),await this.sessionManager.disposeSession()}})}async getStatus(){if(!m)return F;let e=this.sessionManager.getSessionId();if(!e)return F;try{return await m.getStatus(e)}catch(r){throw this.logger?.error("[EpsonPrinter] GetStatus failed",r),C(r)}}async openDrawer(){let e={commands:[{type:"drawer"}]};return this.print(e)}onConnectionChange(e){return this.eventRouter.onConnectionChange(e)}onStatusChange(e){return this.statusController.subscribe(e)}};import{NativeModules as Re}from"react-native";var Z=Re.MunchiEpsonModule,pe={bluetooth:["BT:"],tcp:["TCP:","TCPS:"],usb:["USB:"]},Ne=t=>t.includes("[local_"),Pe=(t,e)=>e?pe[e].some(n=>t.startsWith(n)):!0,Ie=async t=>{if(!Z)return console.warn("[EpsonDiscovery] Native module not found"),[];try{return(await Z.discover({timeout:t.timeout})).map(X).filter(r=>!r||Ne(r.target)?!1:Pe(r.target,t.connectionType))}catch(e){let r=C(e);throw console.error("[EpsonDiscovery] Discovery failed",r),r}};var Se=[[/^TM-m10/i,0],[/^TM-m30III/i,29],[/^TM-m30II/i,21],[/^TM-m30/i,1],[/^TM-m50II/i,30],[/^TM-m50/i,23],[/^TM-m55/i,31],[/^TM-P20II/i,27],[/^TM-P20/i,2],[/^TM-P60II/i,4],[/^TM-P60/i,3],[/^TM-P80II/i,28],[/^TM-P80/i,5],[/^TM-T20/i,6],[/^TM-T60/i,7],[/^TM-T70/i,8],[/^TM-T81/i,9],[/^TM-T82/i,10],[/^TM-T83III/i,19],[/^TM-T83/i,11],[/^TM-T88VII/i,24],[/^TM-T88/i,12],[/^TM-T90KP/i,14],[/^TM-T90/i,13],[/^TM-T100/i,20],[/^TM-U220II/i,32],[/^TM-U220/i,15],[/^TM-U330/i,16],[/^TM-L90LFC/i,25],[/^TM-L90/i,17],[/^TM-L100/i,26],[/^TM-H6000/i,18]],_e=t=>{for(let[e,r]of Se)if(e.test(t))return r;return null};var Oe=t=>{let e=C(t),r=e.message.toUpperCase(),n=t instanceof R?t.isHardwareError:A(t),i=e.translationCode==="printer.error.busy"||r.includes("BUSY")||r.includes("IN_USE")||r.includes("PRINT_BUSY"),o=e.code==="TIMEOUT"||e.translationCode==="printer.error.connection_timeout"||r.includes("TIMEOUT"),T=e.code==="CONNECTION_FAILED"||e.translationCode==="printer.error.offline",c=e.code==="DISCOVERY_FAILED",l="UNKNOWN";return n?l="HARDWARE":i?l="BUSY":o?l="TIMEOUT":T?l="CONNECTION":c?l="DISCOVERY":e.code==="PRINT_FAILED"&&(l="PRINT"),{code:e.code,translationCode:e.translationCode,message:e.message,category:l,isHardwareError:n,retryable:i||o,shouldPauseQueue:n,raw:t}},Ot=t=>Oe(t);import ye from"react";import{createContext as ve,useContext as De,useEffect as Me,useMemo as ee,useState as we}from"react";var te=ve(void 0),bt=({config:t,logger:e,children:r})=>{let[n,i]=we();Me(()=>{e&&z(e)},[e]);let o=ee(()=>{let c={...t,logger:e??t.logger};return ne(c)},[t.lang,t.model,t.target,e]),T=ee(()=>({printer:o,config:t,isReady:!0,error:n}),[o,t,n]);return ye.createElement(te.Provider,{value:T},r)},re=()=>{let t=De(te);if(!t)throw new Error("usePrinter must be used within a PrinterProvider");return t};import{useCallback as B,useEffect as x,useRef as ie,useState as Y}from"react";function Ut(t={}){let{enabled:e=!0}=t,{printer:r,config:n}=re(),[i,o]=Y("DISCONNECTED"),[T,c]=Y(null),[l,p]=Y(null),H=ie("DISCONNECTED"),V=ie(null),d=l!==null,N=B(E=>{V.current=E,p(E)},[]),I=B(E=>{if(E instanceof Error&&E.message){N(E.message);return}if(typeof E=="string"&&E.length>0){N(E);return}N("Unknown printer error")},[N]),a=B(()=>{V.current!==null&&N(null)},[N]);return x(()=>r.onConnectionChange(S=>{H.current=S,o(S),S==="CONNECTED"&&a()}),[a,r]),x(()=>e?r.onStatusChange(S=>{c(S),a()}):void 0,[a,e,r]),x(()=>{e&&i==="CONNECTED"&&r.getStatus().then(E=>{c(E),a()}).catch(I)},[I,a,i,e,r]),x(()=>{let E=H.current;if(e){E==="DISCONNECTED"&&i==="DISCONNECTED"&&r.connect(n.target,5e3).then(a).catch(I);return}(i==="CONNECTED"||i==="CONNECTING")&&r.disconnect().then(a).catch(I)},[I,a,n.target,i,e,r]),{connectionStatus:i,hardwareStatus:T,isError:d,errorMessage:l}}var be="1.0.7";function ne(t){return new b({...t,logger:t.logger??G()})}export{ce as Epos2CallbackCode,ae as Epos2ConnectionEvent,ue as Epos2ErrorStatus,le as Epos2Font,W as Epos2Lang,Q as Epos2StatusEvent,k as EpsonModel,U as FontSize,h as MunchiPrinterError,R as PrinterError,_ as PrinterErrorCode,bt as PrinterProvider,O as PrinterTranslationCode,be as VERSION,Ie as discoverPrinters,G as getGlobalLogger,ne as getPrinter,Ot as resolveEpsonError,_e as resolveModelFromBluetoothName,Oe as resolvePrinterError,z as setGlobalLogger,re as usePrinter,Ut as usePrinterStatus};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorUtils.d.ts","sourceRoot":"","sources":["../../src/utils/errorUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA4C,MAAM,WAAW,CAAC;AAuCzF,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,
|
|
1
|
+
{"version":3,"file":"errorUtils.d.ts","sourceRoot":"","sources":["../../src/utils/errorUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAA4C,MAAM,WAAW,CAAC;AAuCzF,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,kBAgK/C,CAAC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "1.0.
|
|
1
|
+
export declare const VERSION = "1.0.7";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import React
|
|
3
|
+
import UIKit
|
|
3
4
|
|
|
4
5
|
@objc(MunchiEpsonModule)
|
|
5
6
|
class MunchiEpsonModule: RCTEventEmitter, Epos2ConnectionDelegate, Epos2PtrStatusChangeDelegate, Epos2PtrReceiveDelegate, Epos2DiscoveryDelegate {
|
|
@@ -336,6 +337,23 @@ class MunchiEpsonModule: RCTEventEmitter, Epos2ConnectionDelegate, Epos2PtrStatu
|
|
|
336
337
|
if let font = cmd["font"] as? Int {
|
|
337
338
|
p.addTextFont(Int32(font))
|
|
338
339
|
}
|
|
340
|
+
case "addImage":
|
|
341
|
+
if let image = image(for: cmd) {
|
|
342
|
+
let width = Int(image.size.width.rounded(.up))
|
|
343
|
+
let height = Int(image.size.height.rounded(.up))
|
|
344
|
+
p.add(
|
|
345
|
+
image,
|
|
346
|
+
x: 0,
|
|
347
|
+
y: 0,
|
|
348
|
+
width: width,
|
|
349
|
+
height: height,
|
|
350
|
+
color: EPOS2_COLOR_1.rawValue,
|
|
351
|
+
mode: EPOS2_MODE_MONO.rawValue,
|
|
352
|
+
halftone: EPOS2_HALFTONE_DITHER.rawValue,
|
|
353
|
+
brightness: Double(EPOS2_PARAM_DEFAULT),
|
|
354
|
+
compress: EPOS2_COMPRESS_AUTO.rawValue
|
|
355
|
+
)
|
|
356
|
+
}
|
|
339
357
|
default:
|
|
340
358
|
break
|
|
341
359
|
}
|
|
@@ -431,6 +449,40 @@ class MunchiEpsonModule: RCTEventEmitter, Epos2ConnectionDelegate, Epos2PtrStatu
|
|
|
431
449
|
return EPOS2_TM_M30III.rawValue
|
|
432
450
|
}
|
|
433
451
|
|
|
452
|
+
private func image(for command: NSDictionary) -> UIImage? {
|
|
453
|
+
guard let base64 = command["data"] as? String,
|
|
454
|
+
let imageData = Data(base64Encoded: base64),
|
|
455
|
+
let image = UIImage(data: imageData) else {
|
|
456
|
+
return nil
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
let targetWidth = (command["width"] as? NSNumber)?.intValue ?? Int(image.size.width.rounded(.up))
|
|
460
|
+
return resizedImage(image, targetWidth: targetWidth)
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
private func resizedImage(_ image: UIImage, targetWidth: Int) -> UIImage? {
|
|
464
|
+
guard targetWidth > 0 else {
|
|
465
|
+
return image
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
let sourceWidth = max(image.size.width, 1)
|
|
469
|
+
if Int(sourceWidth.rounded(.up)) == targetWidth {
|
|
470
|
+
return image
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
let scale = CGFloat(targetWidth) / sourceWidth
|
|
474
|
+
let targetSize = CGSize(
|
|
475
|
+
width: CGFloat(targetWidth),
|
|
476
|
+
height: max(1, (image.size.height * scale).rounded(.up))
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
UIGraphicsBeginImageContextWithOptions(targetSize, false, 1.0)
|
|
480
|
+
image.draw(in: CGRect(origin: .zero, size: targetSize))
|
|
481
|
+
let resized = UIGraphicsGetImageFromCurrentImageContext()
|
|
482
|
+
UIGraphicsEndImageContext()
|
|
483
|
+
return resized
|
|
484
|
+
}
|
|
485
|
+
|
|
434
486
|
private func teardownPrinter(_ session: EpsonSession, disconnect: Bool) -> Int32? {
|
|
435
487
|
session.printTimeoutWork?.cancel()
|
|
436
488
|
session.printTimeoutWork = nil
|