@munchi_oy/react-native-epson-printer 1.0.6 → 1.0.8

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.
@@ -24,6 +24,7 @@ class MunchiEpsonModule: RCTEventEmitter, Epos2ConnectionDelegate, Epos2PtrStatu
24
24
  private var discoveryResolve: RCTPromiseResolveBlock?
25
25
  private var discoveryReject: RCTPromiseRejectBlock?
26
26
  private var foundPrinters: [NSDictionary] = []
27
+ private let printerQueue = DispatchQueue(label: "com.munchiepsonprinter.epson")
27
28
 
28
29
  override func supportedEvents() -> [String]! {
29
30
  return ["onPrinterStatusChange", "onPrinterConnectionChange", "onPrinterReceive"]
@@ -95,319 +96,354 @@ class MunchiEpsonModule: RCTEventEmitter, Epos2ConnectionDelegate, Epos2PtrStatu
95
96
 
96
97
  @objc(initSession:rejecter:)
97
98
  func initSession(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
98
- let sessionId = UUID().uuidString
99
- sessions[sessionId] = EpsonSession(sessionId: sessionId)
100
- resolve(sessionId)
99
+ printerQueue.async { [weak self] in
100
+ guard let self = self else { return }
101
+
102
+ let sessionId = UUID().uuidString
103
+ self.sessions[sessionId] = EpsonSession(sessionId: sessionId)
104
+ resolve(sessionId)
105
+ }
101
106
  }
102
107
 
103
108
  @objc(disposeSession:resolver:rejecter:)
104
109
  func disposeSession(_ sessionId: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
105
- guard let session = sessions.removeValue(forKey: sessionId) else {
110
+ printerQueue.async { [weak self] in
111
+ guard let self = self else { return }
112
+
113
+ guard let session = self.sessions.removeValue(forKey: sessionId) else {
114
+ resolve(true)
115
+ return
116
+ }
117
+
118
+ self.teardownPrinter(session, disconnect: true)
106
119
  resolve(true)
107
- return
108
120
  }
109
-
110
- teardownPrinter(session, disconnect: true)
111
- resolve(true)
112
121
  }
113
122
 
114
123
  @objc(connect:target:timeout:model:lang:resolver:rejecter:)
115
124
  func connect(_ sessionId: String, target: String, timeout: Double, model: Int, lang: Int, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
116
- guard let session = sessions[sessionId] else {
117
- reject("SESSION_ERROR", "Session not found", nil)
118
- return
119
- }
125
+ printerQueue.async { [weak self] in
126
+ guard let self = self else { return }
120
127
 
121
- var connectionDelay = 0.0
128
+ guard let session = self.sessions[sessionId] else {
129
+ reject("SESSION_ERROR", "Session not found", nil)
130
+ return
131
+ }
122
132
 
123
- if session.printer != nil {
124
- teardownPrinter(session, disconnect: true)
125
- connectionDelay = 0.5
126
- }
133
+ var connectionDelay = 0.0
127
134
 
128
- DispatchQueue.main.asyncAfter(deadline: .now() + connectionDelay) { [weak self] in
129
- guard let self = self else { return }
130
- guard let latestSession = self.sessions[sessionId] else {
131
- reject("SESSION_ERROR", "Session disposed while connecting", nil)
132
- return
135
+ if session.printer != nil {
136
+ self.teardownPrinter(session, disconnect: true)
137
+ connectionDelay = 0.5
133
138
  }
134
139
 
135
- if let ownerSessionId = self.targetToSessionId[target], ownerSessionId != sessionId {
136
- if let ownerSession = self.sessions[ownerSessionId] {
137
- if ownerSession.printResolve != nil {
138
- reject("TARGET_IN_USE", "Target is busy with an active print job: \(target)", nil)
139
- return
140
+ self.printerQueue.asyncAfter(deadline: .now() + connectionDelay) { [weak self] in
141
+ guard let self = self else { return }
142
+ guard let latestSession = self.sessions[sessionId] else {
143
+ reject("SESSION_ERROR", "Session disposed while connecting", nil)
144
+ return
145
+ }
146
+
147
+ if let ownerSessionId = self.targetToSessionId[target], ownerSessionId != sessionId {
148
+ if let ownerSession = self.sessions[ownerSessionId] {
149
+ if ownerSession.printResolve != nil {
150
+ reject("TARGET_IN_USE", "Target is busy with an active print job: \(target)", nil)
151
+ return
152
+ }
153
+ _ = self.teardownPrinter(ownerSession, disconnect: true)
154
+ } else {
155
+ self.targetToSessionId.removeValue(forKey: target)
140
156
  }
141
- _ = self.teardownPrinter(ownerSession, disconnect: true)
142
- } else {
143
- self.targetToSessionId.removeValue(forKey: target)
144
157
  }
145
- }
146
158
 
147
- let safeLang = self.normalizedLanguage(lang)
148
- let safeModel = self.normalizedModel(model)
159
+ let safeLang = self.normalizedLanguage(lang)
160
+ let safeModel = self.normalizedModel(model)
149
161
 
150
- latestSession.printer = Epos2Printer(printerSeries: safeModel, lang: safeLang)
162
+ latestSession.printer = Epos2Printer(printerSeries: safeModel, lang: safeLang)
151
163
 
152
- guard let p = latestSession.printer else {
153
- reject("INIT_ERROR", "Failed to initialize printer object", nil)
154
- return
155
- }
164
+ guard let p = latestSession.printer else {
165
+ reject("INIT_ERROR", "Failed to initialize printer object", nil)
166
+ return
167
+ }
156
168
 
157
- p.setConnectionEventDelegate(self)
158
- p.setStatusChangeEventDelegate(self)
159
- p.setReceiveEventDelegate(self)
160
- self.printerToSessionId[ObjectIdentifier(p)] = sessionId
161
- latestSession.target = target
169
+ p.setConnectionEventDelegate(self)
170
+ p.setStatusChangeEventDelegate(self)
171
+ p.setReceiveEventDelegate(self)
172
+ self.printerToSessionId[ObjectIdentifier(p)] = sessionId
173
+ latestSession.target = target
162
174
 
163
- let connectTimeout = Int(timeout)
164
- let result = p.connect(target, timeout: connectTimeout)
175
+ let connectTimeout = Int(timeout)
176
+ let result = p.connect(target, timeout: connectTimeout)
165
177
 
166
- if result == EPOS2_SUCCESS.rawValue {
167
- _ = p.startMonitor()
168
- self.targetToSessionId[target] = sessionId
169
- resolve("Connected to \(target)")
170
- } else {
171
- self.teardownPrinter(latestSession, disconnect: false)
172
- reject("CONNECT_ERROR", "Failed to connect: \(result)", nil)
178
+ if result == EPOS2_SUCCESS.rawValue {
179
+ _ = p.startMonitor()
180
+ self.targetToSessionId[target] = sessionId
181
+ resolve("Connected to \(target)")
182
+ } else {
183
+ self.teardownPrinter(latestSession, disconnect: false)
184
+ reject("CONNECT_ERROR", "Failed to connect: \(result)", nil)
185
+ }
173
186
  }
174
187
  }
175
188
  }
176
189
 
177
190
  @objc(disconnect:resolver:rejecter:)
178
191
  func disconnect(_ sessionId: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
179
- guard let session = sessions[sessionId] else {
180
- resolve(true)
181
- return
182
- }
192
+ printerQueue.async { [weak self] in
193
+ guard let self = self else { return }
183
194
 
184
- let result = teardownPrinter(session, disconnect: true)
195
+ guard let session = self.sessions[sessionId] else {
196
+ resolve(true)
197
+ return
198
+ }
185
199
 
186
- if result == nil || result == EPOS2_SUCCESS.rawValue {
187
- resolve(true)
188
- } else {
189
- resolve(false)
200
+ let result = self.teardownPrinter(session, disconnect: true)
201
+
202
+ if result == nil || result == EPOS2_SUCCESS.rawValue {
203
+ resolve(true)
204
+ } else {
205
+ resolve(false)
206
+ }
190
207
  }
191
208
  }
192
209
 
193
210
  // --- Delegate Methods ---
194
211
 
195
212
  func onConnection(_ deviceObj: Any!, eventType: Int32) {
196
- guard
197
- let obj = deviceObj as AnyObject?,
198
- let sessionId = printerToSessionId[ObjectIdentifier(obj)],
199
- let session = sessions[sessionId]
200
- else { return }
201
-
202
- var status = "UNKNOWN"
203
- switch eventType {
204
- case EPOS2_EVENT_RECONNECTING.rawValue:
205
- status = "RECONNECTING"
206
- case EPOS2_EVENT_RECONNECT.rawValue:
207
- status = "RECONNECTED"
208
- case EPOS2_EVENT_DISCONNECT.rawValue:
209
- status = "DISCONNECTED"
210
- default:
211
- break
212
- }
213
+ printerQueue.async { [weak self] in
214
+ guard let self = self else { return }
215
+ guard
216
+ let obj = deviceObj as AnyObject?,
217
+ let sessionId = self.printerToSessionId[ObjectIdentifier(obj)],
218
+ let session = self.sessions[sessionId]
219
+ else { return }
220
+
221
+ var status = "UNKNOWN"
222
+ switch eventType {
223
+ case EPOS2_EVENT_RECONNECTING.rawValue:
224
+ status = "RECONNECTING"
225
+ case EPOS2_EVENT_RECONNECT.rawValue:
226
+ status = "RECONNECTED"
227
+ case EPOS2_EVENT_DISCONNECT.rawValue:
228
+ status = "DISCONNECTED"
229
+ default:
230
+ break
231
+ }
213
232
 
214
- sendEvent(withName: "onPrinterConnectionChange", body: [
215
- "sessionId": session.sessionId,
216
- "status": status,
217
- "target": session.target ?? ""
218
- ])
233
+ self.sendEvent(withName: "onPrinterConnectionChange", body: [
234
+ "sessionId": session.sessionId,
235
+ "status": status,
236
+ "target": session.target ?? ""
237
+ ])
238
+ }
219
239
  }
220
240
 
221
241
  func onPtrStatusChange(_ printerObj: Epos2Printer!, eventType: Int32) {
222
- guard
223
- let sessionId = printerToSessionId[ObjectIdentifier(printerObj)],
224
- let session = sessions[sessionId]
225
- else { return }
226
-
227
- sendEvent(withName: "onPrinterStatusChange", body: [
228
- "sessionId": session.sessionId,
229
- "target": session.target ?? "",
230
- "eventType": eventType
231
- ])
242
+ printerQueue.async { [weak self] in
243
+ guard let self = self else { return }
244
+ guard
245
+ let sessionId = self.printerToSessionId[ObjectIdentifier(printerObj)],
246
+ let session = self.sessions[sessionId]
247
+ else { return }
248
+
249
+ self.sendEvent(withName: "onPrinterStatusChange", body: [
250
+ "sessionId": session.sessionId,
251
+ "target": session.target ?? "",
252
+ "eventType": eventType
253
+ ])
254
+ }
232
255
  }
233
256
 
234
257
  func onPtrReceive(_ printerObj: Epos2Printer!, code: Int32, status: Epos2PrinterStatusInfo!, printJobId: String!) {
235
- guard
236
- let sessionId = printerToSessionId[ObjectIdentifier(printerObj)],
237
- let session = sessions[sessionId]
238
- else { return }
239
-
240
- session.printTimeoutWork?.cancel()
241
- session.printTimeoutWork = nil
242
-
243
- if let resolve = session.printResolve, let reject = session.printReject {
244
- if code == EPOS2_CODE_SUCCESS.rawValue {
245
- resolve(true)
246
- } else {
247
- reject("PRINT_FAILURE", "Print finished with error code: \(code)", nil)
258
+ printerQueue.async { [weak self] in
259
+ guard let self = self else { return }
260
+ guard
261
+ let sessionId = self.printerToSessionId[ObjectIdentifier(printerObj)],
262
+ let session = self.sessions[sessionId]
263
+ else { return }
264
+
265
+ session.printTimeoutWork?.cancel()
266
+ session.printTimeoutWork = nil
267
+
268
+ if let resolve = session.printResolve, let reject = session.printReject {
269
+ if code == EPOS2_CODE_SUCCESS.rawValue {
270
+ resolve(true)
271
+ } else {
272
+ reject("PRINT_FAILURE", "Print finished with error code: \(code)", nil)
273
+ }
274
+ session.printResolve = nil
275
+ session.printReject = nil
248
276
  }
249
- session.printResolve = nil
250
- session.printReject = nil
251
- }
252
277
 
253
- sendEvent(withName: "onPrinterReceive", body: [
254
- "sessionId": session.sessionId,
255
- "target": session.target ?? "",
256
- "code": code
257
- ])
278
+ self.sendEvent(withName: "onPrinterReceive", body: [
279
+ "sessionId": session.sessionId,
280
+ "target": session.target ?? "",
281
+ "code": code
282
+ ])
283
+ }
258
284
  }
259
285
 
260
286
  @objc(print:commands:resolver:rejecter:)
261
287
  func print(_ sessionId: String, commands: NSArray, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
262
- guard let session = sessions[sessionId], let p = session.printer else {
263
- reject("PRINT_ERROR", "Printer not connected", nil)
264
- return
265
- }
288
+ printerQueue.async { [weak self] in
289
+ guard let self = self else { return }
290
+ guard let session = self.sessions[sessionId], let p = session.printer else {
291
+ reject("PRINT_ERROR", "Printer not connected", nil)
292
+ return
293
+ }
266
294
 
267
- if session.printResolve != nil {
268
- reject("PRINT_BUSY", "Another print job is in progress", nil)
269
- return
270
- }
295
+ if session.printResolve != nil {
296
+ reject("PRINT_BUSY", "Another print job is in progress", nil)
297
+ return
298
+ }
271
299
 
272
- p.clearCommandBuffer()
273
-
274
- for command in commands {
275
- if let cmd = command as? NSDictionary, let type = cmd["cmd"] as? String {
276
- switch type {
277
- case "addText":
278
- if let data = cmd["data"] as? String {
279
- if let align = cmd["align"] as? String {
280
- var alignVal = EPOS2_ALIGN_LEFT.rawValue
281
- if align == "center" { alignVal = EPOS2_ALIGN_CENTER.rawValue }
282
- else if align == "right" { alignVal = EPOS2_ALIGN_RIGHT.rawValue }
283
- p.addTextAlign(alignVal)
284
- }
285
- if let bold = cmd["bold"] as? Bool {
286
- p.addTextStyle(EPOS2_PARAM_DEFAULT, ul: EPOS2_PARAM_DEFAULT, em: bold ? EPOS2_TRUE : EPOS2_FALSE, color: EPOS2_PARAM_DEFAULT)
287
- }
288
- if let size = cmd["size"] as? String {
289
- }
290
- p.addText(data)
300
+ p.clearCommandBuffer()
301
+
302
+ for command in commands {
303
+ if let cmd = command as? NSDictionary, let type = cmd["cmd"] as? String {
304
+ switch type {
305
+ case "addText":
306
+ if let data = cmd["data"] as? String {
307
+ if let align = cmd["align"] as? String {
308
+ var alignVal = EPOS2_ALIGN_LEFT.rawValue
309
+ if align == "center" { alignVal = EPOS2_ALIGN_CENTER.rawValue }
310
+ else if align == "right" { alignVal = EPOS2_ALIGN_RIGHT.rawValue }
311
+ p.addTextAlign(alignVal)
312
+ }
313
+ if let bold = cmd["bold"] as? Bool {
314
+ p.addTextStyle(EPOS2_PARAM_DEFAULT, ul: EPOS2_PARAM_DEFAULT, em: bold ? EPOS2_TRUE : EPOS2_FALSE, color: EPOS2_PARAM_DEFAULT)
315
+ }
316
+ if let size = cmd["size"] as? String {
317
+ }
318
+ p.addText(data)
319
+ }
320
+ case "addTextAlign":
321
+ if let align = cmd["align"] as? String {
322
+ var alignVal = EPOS2_ALIGN_LEFT.rawValue
323
+ if align == "center" { alignVal = EPOS2_ALIGN_CENTER.rawValue }
324
+ else if align == "right" { alignVal = EPOS2_ALIGN_RIGHT.rawValue }
325
+ p.addTextAlign(alignVal)
326
+ }
327
+ case "addTextStyle":
328
+ if let bold = cmd["bold"] as? Bool {
329
+ p.addTextStyle(EPOS2_PARAM_DEFAULT, ul: EPOS2_PARAM_DEFAULT, em: bold ? EPOS2_TRUE : EPOS2_FALSE, color: EPOS2_PARAM_DEFAULT)
330
+ }
331
+ case "addTextSize":
332
+ if let w = cmd["width"] as? Int, let h = cmd["height"] as? Int {
333
+ p.addTextSize(Int(w), height: Int(h))
334
+ }
335
+ case "addBarcode":
336
+ if let data = cmd["data"] as? String, let typeStr = cmd["type"] as? String {
337
+ var type = EPOS2_BARCODE_CODE39.rawValue
338
+ if typeStr == "UPC-A" { type = EPOS2_BARCODE_UPC_A.rawValue }
339
+ else if typeStr == "UPC-E" { type = EPOS2_BARCODE_UPC_E.rawValue }
340
+ else if typeStr == "EAN13" { type = EPOS2_BARCODE_EAN13.rawValue }
341
+ else if typeStr == "EAN8" { type = EPOS2_BARCODE_EAN8.rawValue }
342
+ else if typeStr == "CODE39" { type = EPOS2_BARCODE_CODE39.rawValue }
343
+ else if typeStr == "ITF" { type = EPOS2_BARCODE_ITF.rawValue }
344
+ else if typeStr == "CODABAR" { type = EPOS2_BARCODE_CODABAR.rawValue }
345
+
346
+ p.addBarcode(data, type: type, hri: EPOS2_HRI_BELOW.rawValue, font: EPOS2_FONT_A.rawValue, width: 2, height: 100)
347
+ }
348
+ case "addSymbol":
349
+ if let data = cmd["data"] as? String {
350
+ p.addSymbol(data, type: EPOS2_SYMBOL_QRCODE_MODEL_2.rawValue, level: EPOS2_LEVEL_M.rawValue, width: 3, height: 3, size: 0)
351
+ }
352
+ case "addCut":
353
+ p.addCut(EPOS2_CUT_FEED.rawValue)
354
+ case "addFeedLine":
355
+ if let line = cmd["line"] as? Int {
356
+ p.addFeedLine(Int(line))
357
+ }
358
+ case "addPulse":
359
+ p.addPulse(EPOS2_DRAWER_2PIN.rawValue, time: EPOS2_PULSE_100.rawValue)
360
+ case "addTextLang":
361
+ if let lang = cmd["lang"] as? Int {
362
+ p.addTextLang(Int32(lang))
363
+ }
364
+ case "addTextFont":
365
+ if let font = cmd["font"] as? Int {
366
+ p.addTextFont(Int32(font))
367
+ }
368
+ case "addImage":
369
+ if let image = self.image(for: cmd) {
370
+ let width = Int(image.size.width.rounded(.up))
371
+ let height = Int(image.size.height.rounded(.up))
372
+ p.add(
373
+ image,
374
+ x: 0,
375
+ y: 0,
376
+ width: width,
377
+ height: height,
378
+ color: EPOS2_COLOR_1.rawValue,
379
+ mode: EPOS2_MODE_MONO.rawValue,
380
+ halftone: EPOS2_HALFTONE_DITHER.rawValue,
381
+ brightness: Double(EPOS2_PARAM_DEFAULT),
382
+ compress: EPOS2_COMPRESS_AUTO.rawValue
383
+ )
384
+ }
385
+ default:
386
+ break
291
387
  }
292
- case "addTextAlign":
293
- if let align = cmd["align"] as? String {
294
- var alignVal = EPOS2_ALIGN_LEFT.rawValue
295
- if align == "center" { alignVal = EPOS2_ALIGN_CENTER.rawValue }
296
- else if align == "right" { alignVal = EPOS2_ALIGN_RIGHT.rawValue }
297
- p.addTextAlign(alignVal)
298
- }
299
- case "addTextStyle":
300
- if let bold = cmd["bold"] as? Bool {
301
- p.addTextStyle(EPOS2_PARAM_DEFAULT, ul: EPOS2_PARAM_DEFAULT, em: bold ? EPOS2_TRUE : EPOS2_FALSE, color: EPOS2_PARAM_DEFAULT)
302
- }
303
- case "addTextSize":
304
- if let w = cmd["width"] as? Int, let h = cmd["height"] as? Int {
305
- p.addTextSize(Int(w), height: Int(h))
306
- }
307
- case "addBarcode":
308
- if let data = cmd["data"] as? String, let typeStr = cmd["type"] as? String {
309
- var type = EPOS2_BARCODE_CODE39.rawValue
310
- if typeStr == "UPC-A" { type = EPOS2_BARCODE_UPC_A.rawValue }
311
- else if typeStr == "UPC-E" { type = EPOS2_BARCODE_UPC_E.rawValue }
312
- else if typeStr == "EAN13" { type = EPOS2_BARCODE_EAN13.rawValue }
313
- else if typeStr == "EAN8" { type = EPOS2_BARCODE_EAN8.rawValue }
314
- else if typeStr == "CODE39" { type = EPOS2_BARCODE_CODE39.rawValue }
315
- else if typeStr == "ITF" { type = EPOS2_BARCODE_ITF.rawValue }
316
- else if typeStr == "CODABAR" { type = EPOS2_BARCODE_CODABAR.rawValue }
317
-
318
- p.addBarcode(data, type: type, hri: EPOS2_HRI_BELOW.rawValue, font: EPOS2_FONT_A.rawValue, width: 2, height: 100)
319
- }
320
- case "addSymbol":
321
- if let data = cmd["data"] as? String {
322
- p.addSymbol(data, type: EPOS2_SYMBOL_QRCODE_MODEL_2.rawValue, level: EPOS2_LEVEL_M.rawValue, width: 3, height: 3, size: 0)
323
- }
324
- case "addCut":
325
- p.addCut(EPOS2_CUT_FEED.rawValue)
326
- case "addFeedLine":
327
- if let line = cmd["line"] as? Int {
328
- p.addFeedLine(Int(line))
329
- }
330
- case "addPulse":
331
- p.addPulse(EPOS2_DRAWER_2PIN.rawValue, time: EPOS2_PULSE_100.rawValue)
332
- case "addTextLang":
333
- if let lang = cmd["lang"] as? Int {
334
- p.addTextLang(Int32(lang))
335
- }
336
- case "addTextFont":
337
- if let font = cmd["font"] as? Int {
338
- p.addTextFont(Int32(font))
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.addImage(
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
- }
357
- default:
358
- break
359
388
  }
360
389
  }
361
- }
362
390
 
363
- session.printResolve = resolve
364
- session.printReject = reject
365
-
366
- let result = p.sendData(Int(EPOS2_PARAM_DEFAULT))
367
- if result != EPOS2_SUCCESS.rawValue {
368
- let errorMsg = getErrorDescription(result)
369
- session.printResolve = nil
370
- session.printReject = nil
371
- reject("PRINT_ERROR", "Failed to send data: \(result) (\(errorMsg))", nil)
372
- } else {
373
- let timeoutWork = DispatchWorkItem { [weak self] in
374
- guard
375
- let self = self,
376
- let timedSession = self.sessions[sessionId]
377
- else { return }
378
-
379
- if let reject = timedSession.printReject {
380
- reject("PRINT_TIMEOUT", "Print timed out waiting for printer response", nil)
391
+ session.printResolve = resolve
392
+ session.printReject = reject
393
+
394
+ let result = p.sendData(Int(EPOS2_PARAM_DEFAULT))
395
+ if result != EPOS2_SUCCESS.rawValue {
396
+ let errorMsg = self.getErrorDescription(result)
397
+ session.printResolve = nil
398
+ session.printReject = nil
399
+ reject("PRINT_ERROR", "Failed to send data: \(result) (\(errorMsg))", nil)
400
+ } else {
401
+ let timeoutWork = DispatchWorkItem { [weak self] in
402
+ guard let self = self else { return }
403
+
404
+ self.printerQueue.async { [weak self] in
405
+ guard
406
+ let self = self,
407
+ let timedSession = self.sessions[sessionId]
408
+ else { return }
409
+
410
+ if let reject = timedSession.printReject {
411
+ reject("PRINT_TIMEOUT", "Print timed out waiting for printer response", nil)
412
+ }
413
+ timedSession.printResolve = nil
414
+ timedSession.printReject = nil
415
+ timedSession.printTimeoutWork = nil
416
+ timedSession.printer?.clearCommandBuffer()
417
+ }
381
418
  }
382
- timedSession.printResolve = nil
383
- timedSession.printReject = nil
384
- timedSession.printTimeoutWork = nil
385
- timedSession.printer?.clearCommandBuffer()
419
+ session.printTimeoutWork = timeoutWork
420
+ DispatchQueue.main.asyncAfter(deadline: .now() + 30, execute: timeoutWork)
386
421
  }
387
- session.printTimeoutWork = timeoutWork
388
- DispatchQueue.main.asyncAfter(deadline: .now() + 30, execute: timeoutWork)
389
422
  }
390
423
  }
391
424
 
392
425
  @objc(getStatus:resolver:rejecter:)
393
426
  func getStatus(_ sessionId: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
394
- guard let session = sessions[sessionId], let p = session.printer else {
395
- reject("STATUS_ERROR", "Printer not connected", nil)
396
- return
397
- }
427
+ printerQueue.async { [weak self] in
428
+ guard let self = self else { return }
429
+ guard let session = self.sessions[sessionId], let p = session.printer else {
430
+ reject("STATUS_ERROR", "Printer not connected", nil)
431
+ return
432
+ }
398
433
 
399
- if let status = p.getStatus() {
400
- let statusDict: [String: Any] = [
401
- "online": status.connection == EPOS2_TRUE,
402
- "coverOpen": status.coverOpen == EPOS2_TRUE,
403
- "paper": status.paper == EPOS2_PAPER_EMPTY.rawValue ? "EMPTY" : (status.paper == EPOS2_PAPER_NEAR_END.rawValue ? "NEAR_EMPTY" : "OK"),
404
- "paperEmpty": status.paper == EPOS2_PAPER_EMPTY.rawValue, // legacy compat
405
- "drawerOpen": status.drawer == EPOS2_DRAWER_HIGH.rawValue, // HIGH typically means open/signal high depending on wiring, assuming HIGH = Open for now based on common usage
406
- "errorStatus": status.errorStatus == EPOS2_MECHANICAL_ERR.rawValue ? "MECHANICAL_ERR" : (status.errorStatus == EPOS2_AUTOCUTTER_ERR.rawValue ? "AUTOCUTTER_ERR" : "NONE")
407
- ]
408
- resolve(statusDict)
409
- } else {
410
- reject("STATUS_ERROR", "Failed to retrieve status", nil)
434
+ if let status = p.getStatus() {
435
+ let statusDict: [String: Any] = [
436
+ "online": status.connection == EPOS2_TRUE,
437
+ "coverOpen": status.coverOpen == EPOS2_TRUE,
438
+ "paper": status.paper == EPOS2_PAPER_EMPTY.rawValue ? "EMPTY" : (status.paper == EPOS2_PAPER_NEAR_END.rawValue ? "NEAR_EMPTY" : "OK"),
439
+ "paperEmpty": status.paper == EPOS2_PAPER_EMPTY.rawValue,
440
+ "drawerOpen": status.drawer == EPOS2_DRAWER_HIGH.rawValue,
441
+ "errorStatus": status.errorStatus == EPOS2_MECHANICAL_ERR.rawValue ? "MECHANICAL_ERR" : (status.errorStatus == EPOS2_AUTOCUTTER_ERR.rawValue ? "AUTOCUTTER_ERR" : "NONE")
442
+ ]
443
+ resolve(statusDict)
444
+ } else {
445
+ reject("STATUS_ERROR", "Failed to retrieve status", nil)
446
+ }
411
447
  }
412
448
  }
413
449
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@munchi_oy/react-native-epson-printer",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Munchi Printer SDK Bridge",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",