@munchi_oy/react-native-label-printer 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -164,48 +164,160 @@ RCT_REMAP_METHOD(checkPrinterAtIp,
164
164
  resolver:(RCTPromiseResolveBlock)resolve
165
165
  rejecter:(RCTPromiseRejectBlock)reject)
166
166
  {
167
- @try {
168
- BRLMChannel *channel = [[BRLMChannel alloc] initWithWifiIPAddress:ipAddress];
169
- if (channel == nil) {
170
- NSMutableDictionary *result = [self errorWithStage:@"channel_create" reason:@"Failed to create BRLMChannel from IP"];
171
- result[@"inputIp"] = ipAddress ?: @"";
172
- resolve(result);
173
- return;
174
- }
167
+ dispatch_async([self labelPrintQueue], ^{
168
+ @try {
169
+ NSInteger maxAttempts = 4;
170
+ NSTimeInterval retryDelay = 1.0;
171
+ NSMutableArray *attemptLogs = [NSMutableArray array];
172
+ NSMutableDictionary *lastFailure = nil;
175
173
 
176
- BRLMPrinterDriverGenerateResult *openResult = [BRLMPrinterDriverGenerator openChannel:channel];
174
+ for (NSInteger attempt = 1; attempt <= maxAttempts; attempt++) {
175
+ id driver = nil;
177
176
 
178
- if (openResult == nil) {
179
- NSMutableDictionary *result = [self errorWithStage:@"open_channel" reason:@"openChannel returned nil"];
180
- result[@"inputIp"] = ipAddress ?: @"";
181
- resolve(result);
182
- return;
183
- }
177
+ @try {
178
+ BRLMChannel *channel = [[BRLMChannel alloc] initWithWifiIPAddress:ipAddress];
179
+ if (channel == nil) {
180
+ lastFailure = [self attemptErrorWithAttempt:attempt
181
+ stage:@"channel_create"
182
+ reason:@"Failed to create BRLMChannel from IP"];
183
+ [attemptLogs addObject:lastFailure];
184
+
185
+ if (attempt < maxAttempts) {
186
+ [NSThread sleepForTimeInterval:retryDelay];
187
+ }
188
+ continue;
189
+ }
190
+
191
+ BRLMPrinterDriverGenerateResult *openResult = [BRLMPrinterDriverGenerator openChannel:channel];
184
192
 
185
- if (openResult.driver == nil) {
186
- NSMutableDictionary *result = [self errorWithStage:@"open_channel"
187
- reason:@"Failed to open printer driver from channel"
188
- extras:@{ @"openChannelError": openResult.error ? [openResult.error description] : @"" }];
193
+ NSInteger openChannelCode = 0;
194
+ NSString *openChannelError = @"";
195
+ if (openResult != nil && openResult.error != nil) {
196
+ openChannelCode = openResult.error.code;
197
+ openChannelError = [openResult.error description] ?: @"";
198
+ }
199
+
200
+ if (openResult == nil || openResult.driver == nil) {
201
+ lastFailure = [self attemptErrorWithAttempt:attempt
202
+ stage:@"open_channel"
203
+ reason:@"Failed to open printer driver from channel"
204
+ extras:@{
205
+ @"openChannelCode": @(openChannelCode),
206
+ @"openChannelError": openChannelError
207
+ }];
208
+ [attemptLogs addObject:lastFailure];
209
+
210
+ // warm-up open/close, same idea as print flow
211
+ if (attempt < maxAttempts) {
212
+ @try {
213
+ BRLMChannel *warmupChannel = [[BRLMChannel alloc] initWithWifiIPAddress:ipAddress];
214
+ if (warmupChannel != nil) {
215
+ BRLMPrinterDriverGenerateResult *warmupResult =
216
+ [BRLMPrinterDriverGenerator openChannel:warmupChannel];
217
+
218
+ if (warmupResult != nil && warmupResult.driver != nil) {
219
+ if ([warmupResult.driver respondsToSelector:@selector(closeChannel)]) {
220
+ [warmupResult.driver closeChannel];
221
+ }
222
+ }
223
+ }
224
+ } @catch (NSException *warmupException) {
225
+ }
226
+
227
+ [NSThread sleepForTimeInterval:retryDelay];
228
+ }
229
+ continue;
230
+ }
231
+
232
+ driver = openResult.driver;
233
+
234
+ // settle time after reconnect/open
235
+ [NSThread sleepForTimeInterval:0.8];
236
+
237
+ BRLMGetPrinterStatusResult *statusResult = nil;
238
+ BOOL printerReady = NO;
239
+
240
+ for (NSInteger statusTry = 1; statusTry <= 3; statusTry++) {
241
+ statusResult = [driver getPrinterStatus];
242
+
243
+ if (statusResult != nil && statusResult.status != nil) {
244
+ printerReady = YES;
245
+ break;
246
+ }
247
+
248
+ if (statusTry < 3) {
249
+ [NSThread sleepForTimeInterval:0.7];
250
+ }
251
+ }
252
+
253
+ if (!printerReady) {
254
+ if (driver && [driver respondsToSelector:@selector(closeChannel)]) {
255
+ [driver closeChannel];
256
+ }
257
+
258
+ lastFailure = [self attemptErrorWithAttempt:attempt
259
+ stage:@"get_status"
260
+ reason:@"Failed to get printer status after reconnect"
261
+ extras:@{
262
+ @"statusAvailable": @(statusResult != nil),
263
+ @"statusObjectAvailable": @((statusResult != nil && statusResult.status != nil))
264
+ }];
265
+ [attemptLogs addObject:lastFailure];
266
+
267
+ if (attempt < maxAttempts) {
268
+ [NSThread sleepForTimeInterval:retryDelay];
269
+ }
270
+ continue;
271
+ }
272
+
273
+ NSDictionary *success = @{
274
+ @"ok": @YES,
275
+ @"inputIp": ipAddress ?: @"",
276
+ @"stage": @"open_channel_success",
277
+ @"attempt": @(attempt),
278
+ @"attemptLogs": attemptLogs
279
+ };
280
+
281
+ if (driver && [driver respondsToSelector:@selector(closeChannel)]) {
282
+ [driver closeChannel];
283
+ }
284
+
285
+ resolve(success);
286
+ return;
287
+
288
+ } @catch (NSException *innerException) {
289
+ if (driver && [driver respondsToSelector:@selector(closeChannel)]) {
290
+ [driver closeChannel];
291
+ }
292
+
293
+ lastFailure = [self attemptErrorWithAttempt:attempt
294
+ stage:@"exception"
295
+ reason:innerException.reason ?: @"Unknown native exception"];
296
+ [attemptLogs addObject:lastFailure];
297
+
298
+ if (attempt < maxAttempts) {
299
+ [NSThread sleepForTimeInterval:retryDelay];
300
+ }
301
+ }
302
+ }
303
+
304
+ NSMutableDictionary *result = [self errorWithStage:@"retry_exhausted"
305
+ reason:@"Printer connection test failed after all recovery attempts"];
189
306
  result[@"inputIp"] = ipAddress ?: @"";
307
+ result[@"attemptLogs"] = attemptLogs;
308
+
309
+ if (lastFailure != nil) {
310
+ result[@"lastFailureStage"] = lastFailure[@"stage"] ?: @"unknown";
311
+ result[@"lastFailureReason"] = lastFailure[@"reason"] ?: @"Unknown error";
312
+ result[@"lastFailureDetails"] = lastFailure;
313
+ }
314
+
190
315
  resolve(result);
191
- return;
192
- }
193
316
 
194
- if ([openResult.driver respondsToSelector:@selector(closeChannel)]) {
195
- [openResult.driver closeChannel];
317
+ } @catch (NSException *exception) {
318
+ reject(@"CHECK_PRINTER_IP_ERROR", exception.reason, nil);
196
319
  }
197
-
198
- resolve(@{
199
- @"ok": @YES,
200
- @"inputIp": ipAddress ?: @"",
201
- @"stage": @"open_channel_success",
202
- @"channelInfo": channel.channelInfo ?: @"",
203
- @"extraInfo": channel.extraInfo ?: @{},
204
- @"driverClass": NSStringFromClass([openResult.driver class])
205
- });
206
- } @catch (NSException *exception) {
207
- reject(@"CHECK_PRINTER_IP_ERROR", exception.reason, nil);
208
- }
320
+ });
209
321
  }
210
322
 
211
323
  RCT_REMAP_METHOD(printLabel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@munchi_oy/react-native-label-printer",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "React Native bridge for label printers",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",