@spencerls/react-native-nfc 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -30,17 +30,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- NfcProvider: () => NfcProvider,
34
33
  nfc: () => nfc,
35
34
  nfcNdefTag: () => nfcNdefTag,
36
35
  nfcService: () => nfcService,
37
36
  nfcTag: () => nfcTag,
38
37
  nfcVTag: () => nfcVTag,
39
- useNfc: () => useNfc,
40
- useNfcContext: () => useNfcContext,
41
- useNfcReader: () => useNfcReader,
42
- useNfcState: () => useNfcState,
43
- useNfcTechnology: () => useNfcTechnology
38
+ useNfcTagEvent: () => useNfcTagEvent,
39
+ useNfcTagEventLoop: () => useNfcTagEventLoop,
40
+ useNfcTech: () => useNfcTech,
41
+ useNfcTechLoop: () => useNfcTechLoop
44
42
  });
45
43
  module.exports = __toCommonJS(index_exports);
46
44
 
@@ -171,224 +169,14 @@ __export(operations_exports4, {
171
169
  });
172
170
  var import_react_native_nfc_manager6 = __toESM(require("react-native-nfc-manager"));
173
171
 
174
- // src/nfc/service.ts
175
- var import_react_native2 = require("react-native");
176
- var import_react_native_nfc_manager4 = __toESM(require("react-native-nfc-manager"));
177
-
178
- // src/nfc/error.ts
179
- var NfcError = class extends Error {
180
- constructor(message) {
181
- super(`[NFC] ${message}`);
182
- }
183
- };
184
-
185
- // src/nfc/service.ts
186
- var NfcService = class {
187
- constructor() {
188
- this.state = { mode: "idle", tag: null };
189
- this.listeners = /* @__PURE__ */ new Set();
190
- this.isProcessingTag = false;
191
- this.currentCooldownMs = 1500;
192
- this.readerModeFlags_ANDROID = null;
193
- import_react_native_nfc_manager4.default.start();
194
- }
195
- enableReaderMode_ANDROID(flags) {
196
- if (import_react_native2.Platform.OS !== "android") return;
197
- this.readerModeFlags_ANDROID = flags;
198
- }
199
- // -----------------------------
200
- // Internal state management
201
- // -----------------------------
202
- setState(partial) {
203
- this.state = { ...this.state, ...partial };
204
- for (const listener of this.listeners) listener(this.state);
205
- }
206
- getState() {
207
- return this.state;
208
- }
209
- subscribe(fn) {
210
- this.listeners.add(fn);
211
- fn(this.state);
212
- return () => {
213
- this.listeners.delete(fn);
214
- };
215
- }
216
- // -----------------------------
217
- // START READER (Soft Continuous Mode)
218
- // -----------------------------
219
- async startReader(onTag, options) {
220
- var _a;
221
- if (this.state.mode !== "idle") {
222
- console.warn(`[NFC] Cannot start reader while ${this.state.mode}`);
223
- return;
224
- }
225
- this.currentOnTag = onTag;
226
- this.currentCooldownMs = (_a = options == null ? void 0 : options.cooldownMs) != null ? _a : 1500;
227
- this.isProcessingTag = false;
228
- this.setState({ mode: "starting", tag: null });
229
- import_react_native_nfc_manager4.default.setEventListener(
230
- import_react_native_nfc_manager4.NfcEvents.DiscoverTag,
231
- async (tag) => {
232
- var _a2;
233
- if (!tag) return;
234
- if (this.isProcessingTag) return;
235
- this.isProcessingTag = true;
236
- this.setState({ tag, mode: "active" });
237
- try {
238
- await ((_a2 = this.currentOnTag) == null ? void 0 : _a2.call(this, tag));
239
- } catch (err) {
240
- console.warn("[NFC] onTag handler error:", err);
241
- } finally {
242
- const cooldown = this.currentCooldownMs;
243
- if (this.cooldownTimer) {
244
- clearTimeout(this.cooldownTimer);
245
- }
246
- this.cooldownTimer = setTimeout(() => {
247
- this.isProcessingTag = false;
248
- this.setState({ tag: null });
249
- this.cooldownTimer = void 0;
250
- }, cooldown);
251
- }
252
- }
253
- );
254
- try {
255
- if (this.readerModeFlags_ANDROID) {
256
- await import_react_native_nfc_manager4.default.registerTagEvent({
257
- isReaderModeEnabled: true,
258
- readerModeFlags: this.readerModeFlags_ANDROID
259
- });
260
- } else {
261
- await import_react_native_nfc_manager4.default.registerTagEvent();
262
- }
263
- if (this.state.mode === "starting") {
264
- this.setState({ mode: "active" });
265
- }
266
- } catch (err) {
267
- console.warn("[NFC] startReader error:", err);
268
- this._resetReaderState();
269
- }
270
- }
271
- // -----------------------------
272
- // STOP READER (explicit only)
273
- // -----------------------------
274
- async stopReader() {
275
- if (["idle", "stopping"].includes(this.state.mode)) return;
276
- this.setState({ mode: "stopping" });
277
- import_react_native_nfc_manager4.default.setEventListener(import_react_native_nfc_manager4.NfcEvents.DiscoverTag, () => {
278
- });
279
- if (this.cooldownTimer) {
280
- clearTimeout(this.cooldownTimer);
281
- this.cooldownTimer = void 0;
282
- }
283
- try {
284
- await import_react_native_nfc_manager4.default.unregisterTagEvent();
285
- } catch (err) {
286
- console.warn("[NFC] unregisterTagEvent error:", err);
287
- }
288
- this._resetReaderState();
289
- }
290
- _resetReaderState() {
291
- if (this.cooldownTimer) {
292
- clearTimeout(this.cooldownTimer);
293
- this.cooldownTimer = void 0;
294
- }
295
- this.setState({ mode: "idle", tag: null });
296
- this.currentOnTag = void 0;
297
- this.isProcessingTag = false;
298
- }
299
- // -----------------------------
300
- // Technology sessions (NDEF, NfcV, etc.)
301
- // -----------------------------
302
- async withTechnology(tech3, handler) {
303
- if (this.state.mode === "technology") {
304
- throw new NfcError("Technology is already in use!");
305
- }
306
- if (this.readerModeFlags_ANDROID) {
307
- return this.withTechnologyReaderMode_ANDROID(
308
- tech3,
309
- handler,
310
- this.readerModeFlags_ANDROID
311
- );
312
- }
313
- const readerWasActive = ["starting", "active", "stopping"].includes(
314
- this.state.mode
315
- );
316
- const savedOnTag = this.currentOnTag;
317
- const savedCooldown = this.currentCooldownMs;
318
- if (readerWasActive) {
319
- await this.stopReader();
320
- }
321
- if (this.state.mode !== "idle") {
322
- throw new NfcError(
323
- `Cannot start technology session in mode ${this.state.mode}`
324
- );
325
- }
326
- this.setState({ mode: "technology" });
327
- try {
328
- await import_react_native_nfc_manager4.default.requestTechnology(tech3, {
329
- alertMessage: "Hold near NFC tag"
330
- });
331
- const result = await handler();
332
- if (import_react_native2.Platform.OS === "ios") {
333
- await import_react_native_nfc_manager4.default.setAlertMessageIOS("Success!");
334
- }
335
- return result;
336
- } catch (err) {
337
- const message = typeof err === "string" ? err : (err == null ? void 0 : err.message) || "Unknown NFC error";
338
- throw new NfcError(`withTechnology error: ${message}`);
339
- } finally {
340
- try {
341
- await import_react_native_nfc_manager4.default.cancelTechnologyRequest();
342
- } catch {
343
- }
344
- this.setState({ mode: "idle", tag: null });
345
- if (readerWasActive) {
346
- try {
347
- await this.startReader(savedOnTag, { cooldownMs: savedCooldown });
348
- } catch (err) {
349
- console.warn(
350
- "[NFC] Failed to restart reader after tech session",
351
- err
352
- );
353
- }
354
- }
355
- }
356
- }
357
- async withTechnologyReaderMode_ANDROID(tech3, handler, flags) {
358
- const readerWasActive = ["starting", "active", "stopping"].includes(
359
- this.state.mode
360
- );
361
- this.isProcessingTag = true;
362
- this.setState({ mode: "technology" });
363
- try {
364
- await import_react_native_nfc_manager4.default.requestTechnology(tech3, {
365
- isReaderModeEnabled: true,
366
- readerModeFlags: flags
367
- });
368
- return await handler();
369
- } catch (err) {
370
- const message = typeof err === "string" ? err : (err == null ? void 0 : err.message) || "Unknown NFC error";
371
- throw new NfcError(`withTechnologyReaderMode_ANDROID error: ${message}`);
372
- } finally {
373
- try {
374
- await import_react_native_nfc_manager4.default.cancelTechnologyRequest();
375
- } catch {
376
- }
377
- this.isProcessingTag = false;
378
- this.setState({ mode: readerWasActive ? "active" : "idle" });
379
- }
380
- }
381
- };
382
- var nfcService = new NfcService();
383
-
384
172
  // src/nfc/tag/internal/operations.ts
385
173
  var operations_exports2 = {};
386
174
  __export(operations_exports2, {
387
175
  getTag: () => getTag
388
176
  });
389
- var import_react_native_nfc_manager5 = __toESM(require("react-native-nfc-manager"));
177
+ var import_react_native_nfc_manager4 = __toESM(require("react-native-nfc-manager"));
390
178
  async function getTag() {
391
- const tagEvent = await import_react_native_nfc_manager5.default.getTag();
179
+ const tagEvent = await import_react_native_nfc_manager4.default.getTag();
392
180
  if (!tagEvent) throw new Error("No tag detected");
393
181
  return tagEvent;
394
182
  }
@@ -403,8 +191,67 @@ var operations_exports3 = {};
403
191
  __export(operations_exports3, {
404
192
  getTag: () => getTag2
405
193
  });
194
+
195
+ // src/nfc/primitives.ts
196
+ var import_react_native_nfc_manager5 = __toESM(require("react-native-nfc-manager"));
197
+ var _NfcPrimitives = class _NfcPrimitives {
198
+ static async cleanTechnology() {
199
+ await _NfcPrimitives.stopTechnology();
200
+ _NfcPrimitives.isCancellingTechnology = false;
201
+ }
202
+ static async startTechnology(tech3, options) {
203
+ if (_NfcPrimitives.isRequestingTechnology) {
204
+ throw new Error("Technology already started");
205
+ }
206
+ _NfcPrimitives.isRequestingTechnology = true;
207
+ try {
208
+ console.log("Technology started");
209
+ await import_react_native_nfc_manager5.default.requestTechnology(tech3, options);
210
+ } finally {
211
+ _NfcPrimitives.isRequestingTechnology = false;
212
+ }
213
+ }
214
+ static async stopTechnology() {
215
+ if (_NfcPrimitives.isCancellingTechnology) return;
216
+ _NfcPrimitives.isCancellingTechnology = true;
217
+ try {
218
+ await import_react_native_nfc_manager5.default.cancelTechnologyRequest();
219
+ console.log("Technology stopped");
220
+ } catch (_e) {
221
+ } finally {
222
+ _NfcPrimitives.isCancellingTechnology = false;
223
+ }
224
+ }
225
+ static async withTechnology(tech3, callback, options) {
226
+ let res;
227
+ try {
228
+ await _NfcPrimitives.startTechnology(tech3, options);
229
+ res = await callback();
230
+ } finally {
231
+ await _NfcPrimitives.stopTechnology();
232
+ }
233
+ return res;
234
+ }
235
+ static async getTag() {
236
+ return await import_react_native_nfc_manager5.default.getTag();
237
+ }
238
+ static async registerTagEvent(options) {
239
+ await import_react_native_nfc_manager5.default.registerTagEvent(options);
240
+ }
241
+ static async unregisterTagEvent() {
242
+ await import_react_native_nfc_manager5.default.unregisterTagEvent();
243
+ }
244
+ static setEventListener(event, handler) {
245
+ import_react_native_nfc_manager5.default.setEventListener(event, handler);
246
+ }
247
+ };
248
+ _NfcPrimitives.isRequestingTechnology = false;
249
+ _NfcPrimitives.isCancellingTechnology = false;
250
+ var NfcPrimitives = _NfcPrimitives;
251
+
252
+ // src/nfc/tag/operations.ts
406
253
  async function getTag2(tech3) {
407
- return nfcService.withTechnology(tech3, nfcTag.getTag);
254
+ return NfcPrimitives.withTechnology(tech3, nfcTag.getTag);
408
255
  }
409
256
 
410
257
  // src/nfc/ndef/operations.ts
@@ -412,13 +259,13 @@ async function getStatus() {
412
259
  return await import_react_native_nfc_manager6.default.ndefHandler.getNdefStatus();
413
260
  }
414
261
  async function readMessage2() {
415
- return await nfcService.withTechnology(
262
+ return await NfcPrimitives.withTechnology(
416
263
  nfcNdefTag.tech,
417
264
  nfcNdefTag.readMessage
418
265
  );
419
266
  }
420
267
  async function readFull() {
421
- return await nfcService.withTechnology(nfcNdefTag.tech, async () => {
268
+ return await NfcPrimitives.withTechnology(nfcNdefTag.tech, async () => {
422
269
  const tag = await nfcTag.getTag();
423
270
  const message = await nfcNdefTag.readMessage();
424
271
  return { message, tag };
@@ -428,7 +275,7 @@ async function write2(records) {
428
275
  if (!records || records.length === 0) {
429
276
  throw new NdefError("write: no NDEF records provided");
430
277
  }
431
- await nfcService.withTechnology(
278
+ await NfcPrimitives.withTechnology(
432
279
  nfcNdefTag.tech,
433
280
  async () => await nfcNdefTag.write(records)
434
281
  );
@@ -469,12 +316,317 @@ async function writeExternal(domain, type, payload, id) {
469
316
  await write2([rec]);
470
317
  }
471
318
  async function makeReadOnly() {
472
- await nfcService.withTechnology(
319
+ await NfcPrimitives.withTechnology(
473
320
  nfcNdefTag.tech,
474
321
  import_react_native_nfc_manager6.default.ndefHandler.makeReadOnly
475
322
  );
476
323
  }
477
324
 
325
+ // src/nfc/service/state/index.ts
326
+ var NfcStateMachine = class {
327
+ constructor() {
328
+ this.state = "idle" /* IDLE */;
329
+ this.currentJob = null;
330
+ }
331
+ async transition(to, strategy) {
332
+ if (!this.currentJob) {
333
+ throw new Error("No current job");
334
+ }
335
+ if (!strategy.canHandle(this.currentJob)) {
336
+ throw new Error(
337
+ `Strategy ${strategy.constructor.name} cannot handle ${this.currentJob.type}`
338
+ );
339
+ }
340
+ console.log(`\u{1F504} ${this.state} \u2192 ${to}`);
341
+ this.state = to;
342
+ }
343
+ getState() {
344
+ return this.state;
345
+ }
346
+ setCurrentJob(job) {
347
+ this.currentJob = job;
348
+ }
349
+ async transitionToIdle() {
350
+ console.log("\u{1F504} Transitioning to idle");
351
+ this.state = "idle" /* IDLE */;
352
+ this.currentJob = null;
353
+ }
354
+ async stop() {
355
+ if (this.state === "idle" /* IDLE */) return;
356
+ if (!this.isLoopingState()) return;
357
+ console.log("\u{1F504} Transitioning to stopping");
358
+ this.state = "stopping" /* STOPPING */;
359
+ }
360
+ isLoopingState() {
361
+ return ["tech_loop" /* TECH_LOOP */, "tag_event_loop" /* TAG_EVENT_LOOP */].includes(this.state);
362
+ }
363
+ };
364
+
365
+ // src/nfc/error.ts
366
+ var NfcError = class extends Error {
367
+ constructor(message) {
368
+ super(`[NFC] ${message}`);
369
+ }
370
+ };
371
+
372
+ // src/nfc/service/strategies/error.ts
373
+ var NfcStrategyError = class extends NfcError {
374
+ constructor(message, strategy) {
375
+ super(`[${strategy}] ${message}`);
376
+ }
377
+ };
378
+
379
+ // src/nfc/service/strategies/tag-event.ts
380
+ var import_react_native_nfc_manager7 = require("react-native-nfc-manager");
381
+ var TagEventStrategy = class {
382
+ canHandle(job) {
383
+ return job.type === "tag_event" /* TAG_EVENT */;
384
+ }
385
+ async execute(job, stateMachine) {
386
+ const { onTag, options } = job;
387
+ NfcPrimitives.setEventListener(import_react_native_nfc_manager7.NfcEvents.DiscoverTag, null);
388
+ try {
389
+ await NfcPrimitives.registerTagEvent(options);
390
+ } catch (err) {
391
+ NfcPrimitives.setEventListener(import_react_native_nfc_manager7.NfcEvents.DiscoverTag, null);
392
+ throw new NfcStrategyError(
393
+ `TagEvent registration failed: ${err.message}`,
394
+ this.constructor.name
395
+ );
396
+ }
397
+ return new Promise((resolve, reject) => {
398
+ let done = false;
399
+ const handler = async (tag) => {
400
+ if (done) return;
401
+ done = true;
402
+ try {
403
+ await onTag(tag);
404
+ resolve();
405
+ } catch (err) {
406
+ reject(
407
+ new NfcStrategyError(
408
+ `Tag processing failed: ${err.message}`,
409
+ this.constructor.name
410
+ )
411
+ );
412
+ } finally {
413
+ NfcPrimitives.setEventListener(import_react_native_nfc_manager7.NfcEvents.DiscoverTag, null);
414
+ try {
415
+ await NfcPrimitives.unregisterTagEvent();
416
+ } catch {
417
+ }
418
+ }
419
+ };
420
+ NfcPrimitives.setEventListener(import_react_native_nfc_manager7.NfcEvents.DiscoverTag, handler);
421
+ });
422
+ }
423
+ };
424
+
425
+ // src/nfc/service/strategies/tag-event-loop.ts
426
+ var import_react_native_nfc_manager8 = require("react-native-nfc-manager");
427
+ var TagEventLoopStrategy = class {
428
+ canHandle(job) {
429
+ return job.type === "tag_event_loop" /* TAG_EVENT_LOOP */;
430
+ }
431
+ async execute(job, stateMachine) {
432
+ const { onTag, options } = job;
433
+ let isProcessingTag = false;
434
+ let cooldownTimer;
435
+ const handleTagEvent = async (tag) => {
436
+ if (!tag || isProcessingTag) return;
437
+ isProcessingTag = true;
438
+ try {
439
+ await onTag(tag);
440
+ } catch (err) {
441
+ console.warn("[NFC] Tag processing failed:", err);
442
+ } finally {
443
+ isProcessingTag = false;
444
+ }
445
+ };
446
+ NfcPrimitives.setEventListener(import_react_native_nfc_manager8.NfcEvents.DiscoverTag, handleTagEvent);
447
+ try {
448
+ await NfcPrimitives.registerTagEvent(options);
449
+ await new Promise((resolve) => {
450
+ const interval = setInterval(() => {
451
+ if (stateMachine.getState() === "stopping" /* STOPPING */) {
452
+ clearInterval(interval);
453
+ resolve();
454
+ }
455
+ }, 100);
456
+ });
457
+ } catch (err) {
458
+ throw new NfcStrategyError(
459
+ `TagEvent loop failed: ${err.message}`,
460
+ this.constructor.name
461
+ );
462
+ } finally {
463
+ NfcPrimitives.setEventListener(import_react_native_nfc_manager8.NfcEvents.DiscoverTag, null);
464
+ await NfcPrimitives.unregisterTagEvent().catch(() => {
465
+ });
466
+ if (cooldownTimer) clearTimeout(cooldownTimer);
467
+ }
468
+ }
469
+ };
470
+
471
+ // src/nfc/service/strategies/tech.ts
472
+ var TechStrategy = class {
473
+ canHandle(job) {
474
+ return job.type === "tech" /* TECH */;
475
+ }
476
+ async execute(job, stateMachine) {
477
+ const { tech: tech3, withTechnology, afterTechnology, options } = job;
478
+ await NfcPrimitives.withTechnology(tech3, withTechnology, options);
479
+ if (afterTechnology) {
480
+ await afterTechnology();
481
+ }
482
+ }
483
+ };
484
+
485
+ // src/nfc/service/strategies/tech-loop.ts
486
+ var TechLoopStrategy = class {
487
+ canHandle(job) {
488
+ return job.type === "tech_loop" /* TECH_LOOP */;
489
+ }
490
+ async execute(job, stateMachine) {
491
+ const { tech: tech3, withTechnology, afterTechnology, options } = job;
492
+ while (true) {
493
+ if (stateMachine.getState() === "stopping" /* STOPPING */) break;
494
+ try {
495
+ await NfcPrimitives.withTechnology(tech3, withTechnology, options);
496
+ } catch (e) {
497
+ if (await handleStartTechError(e)) {
498
+ continue;
499
+ }
500
+ break;
501
+ }
502
+ if (afterTechnology) {
503
+ await afterTechnology();
504
+ }
505
+ }
506
+ }
507
+ };
508
+ async function handleStartTechError(e) {
509
+ if (e.message.includes("UserCancel")) {
510
+ console.log("withTechnology() Cancelled");
511
+ return true;
512
+ }
513
+ if (e.message === "Technology already started") {
514
+ console.warn("withTechnology() Already started");
515
+ await NfcPrimitives.stopTechnology();
516
+ return true;
517
+ }
518
+ console.error("withTechnology() failed", e.message);
519
+ return false;
520
+ }
521
+
522
+ // src/nfc/service/index.ts
523
+ var NfcService = class _NfcService {
524
+ constructor() {
525
+ this.strategies = [
526
+ new TagEventStrategy(),
527
+ new TagEventLoopStrategy(),
528
+ new TechStrategy(),
529
+ new TechLoopStrategy()
530
+ ];
531
+ this.stateMachine = new NfcStateMachine();
532
+ this.jobRetry = null;
533
+ this.isExecutingJobs = false;
534
+ }
535
+ static getInstance() {
536
+ if (!_NfcService.instance) _NfcService.instance = new _NfcService();
537
+ return _NfcService.instance;
538
+ }
539
+ async startTech(tech3, withTechnology, afterTechnology, options) {
540
+ const job = {
541
+ type: "tech" /* TECH */,
542
+ tech: tech3,
543
+ withTechnology,
544
+ afterTechnology,
545
+ options
546
+ };
547
+ await this.executeOrQueue(job);
548
+ }
549
+ async startTechLoop(tech3, withTechnology, afterTechnology, options) {
550
+ const job = {
551
+ type: "tech_loop" /* TECH_LOOP */,
552
+ tech: tech3,
553
+ withTechnology,
554
+ afterTechnology,
555
+ options
556
+ };
557
+ this.executeOrQueue(job);
558
+ }
559
+ async startTagEvent(onTag) {
560
+ const job = {
561
+ type: "tag_event" /* TAG_EVENT */,
562
+ onTag
563
+ };
564
+ await this.executeOrQueue(job);
565
+ }
566
+ async startTagEventLoop(onTag, options) {
567
+ const job = {
568
+ type: "tag_event_loop" /* TAG_EVENT_LOOP */,
569
+ onTag,
570
+ options
571
+ };
572
+ await this.executeOrQueue(job);
573
+ }
574
+ async stop() {
575
+ console.log("\u{1F6D1} Stopping NFC");
576
+ this.jobRetry = null;
577
+ await this.stateMachine.stop();
578
+ }
579
+ async executeOrQueue(job) {
580
+ const state = this.stateMachine.getState();
581
+ if (state === "stopping" /* STOPPING */) {
582
+ console.log("\u{1F504} Setting retry job:", job.type);
583
+ this.jobRetry = job;
584
+ return;
585
+ }
586
+ await this.executeJob(job);
587
+ }
588
+ async executeJob(job) {
589
+ if (this.isExecutingJobs) return;
590
+ this.isExecutingJobs = true;
591
+ let _nextJob = job;
592
+ while (_nextJob) {
593
+ const strategy = this.strategies.find((s) => s.canHandle(job));
594
+ if (!strategy) throw new Error(`No strategy for ${job.type}`);
595
+ this.stateMachine.setCurrentJob(job);
596
+ try {
597
+ const targetState = mapJobTypeToState(job.type);
598
+ await this.stateMachine.transition(targetState, strategy);
599
+ console.log(`\u{1F680} Starting ${job.type} via ${strategy.constructor.name}`);
600
+ await strategy.execute(job, this.stateMachine);
601
+ console.log(`\u2705 Completed ${job.type}`);
602
+ } catch (error) {
603
+ console.error(`\u274C ${job.type} failed:`, error);
604
+ throw error;
605
+ } finally {
606
+ await this.stateMachine.transitionToIdle();
607
+ if (this.jobRetry) {
608
+ console.log("\u{1F504} Retrying job:", this.jobRetry.type);
609
+ }
610
+ _nextJob = this.jobRetry;
611
+ }
612
+ }
613
+ this.isExecutingJobs = false;
614
+ }
615
+ };
616
+ function mapJobTypeToState(type) {
617
+ switch (type) {
618
+ case "tech" /* TECH */:
619
+ return "tech" /* TECH */;
620
+ case "tech_loop" /* TECH_LOOP */:
621
+ return "tech_loop" /* TECH_LOOP */;
622
+ case "tag_event" /* TAG_EVENT */:
623
+ return "tag_event" /* TAG_EVENT */;
624
+ case "tag_event_loop" /* TAG_EVENT_LOOP */:
625
+ return "tag_event_loop" /* TAG_EVENT_LOOP */;
626
+ }
627
+ }
628
+ var nfcService = NfcService.getInstance();
629
+
478
630
  // src/nfc/v/internal/operations.ts
479
631
  var operations_exports5 = {};
480
632
  __export(operations_exports5, {
@@ -485,7 +637,7 @@ __export(operations_exports5, {
485
637
  writeBlock: () => writeBlock,
486
638
  writeBlocks: () => writeBlocks
487
639
  });
488
- var import_react_native_nfc_manager7 = __toESM(require("react-native-nfc-manager"));
640
+ var import_react_native_nfc_manager9 = __toESM(require("react-native-nfc-manager"));
489
641
 
490
642
  // src/nfc/v/error.ts
491
643
  var VError = class extends Error {
@@ -626,7 +778,7 @@ function detectManufacturer(uid) {
626
778
 
627
779
  // src/nfc/v/internal/operations.ts
628
780
  async function transceive(bytes) {
629
- return await import_react_native_nfc_manager7.default.nfcVHandler.transceive(bytes);
781
+ return await import_react_native_nfc_manager9.default.nfcVHandler.transceive(bytes);
630
782
  }
631
783
  async function readBlock(tagId, blockNumber) {
632
784
  const uid = reverseUid(tagId);
@@ -666,9 +818,9 @@ async function getSystemInfo() {
666
818
  }
667
819
 
668
820
  // src/nfc/v/internal/tech.ts
669
- var import_react_native3 = require("react-native");
670
- var import_react_native_nfc_manager8 = require("react-native-nfc-manager");
671
- var tech2 = import_react_native3.Platform.OS === "ios" ? [import_react_native_nfc_manager8.NfcTech.Iso15693IOS] : import_react_native_nfc_manager8.NfcTech.NfcV;
821
+ var import_react_native2 = require("react-native");
822
+ var import_react_native_nfc_manager10 = require("react-native-nfc-manager");
823
+ var tech2 = import_react_native2.Platform.OS === "ios" ? [import_react_native_nfc_manager10.NfcTech.Iso15693IOS] : [import_react_native_nfc_manager10.NfcTech.NfcV];
672
824
 
673
825
  // src/nfc/v/internal/index.ts
674
826
  var nfcVTag = {
@@ -687,35 +839,35 @@ __export(operations_exports6, {
687
839
  writeBlocks: () => writeBlocks2
688
840
  });
689
841
  async function writeBlock2(blockNumber, data) {
690
- await nfcService.withTechnology(nfcVTag.tech, async () => {
842
+ await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
691
843
  const tag = await nfcTag.getTag();
692
844
  if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
693
845
  await nfcVTag.writeBlock(tag.id, blockNumber, data);
694
846
  });
695
847
  }
696
848
  async function writeBlocks2(blockNumber, data) {
697
- await nfcService.withTechnology(nfcVTag.tech, async () => {
849
+ await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
698
850
  const tag = await nfcTag.getTag();
699
851
  if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
700
852
  nfcVTag.writeBlocks(tag.id, blockNumber, data);
701
853
  });
702
854
  }
703
855
  async function readBlock2(blockNumber) {
704
- return await nfcService.withTechnology(nfcVTag.tech, async () => {
856
+ return await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
705
857
  const tag = await nfcTag.getTag();
706
858
  if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
707
859
  return await nfcVTag.readBlock(tag.id, blockNumber);
708
860
  });
709
861
  }
710
862
  async function readBlocks2(startBlock, endBlock) {
711
- return await nfcService.withTechnology(nfcVTag.tech, async () => {
863
+ return await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
712
864
  const tag = await nfcTag.getTag();
713
865
  if (!(tag == null ? void 0 : tag.id)) throw new Error("No NFC-V tag id detected");
714
866
  return await nfcVTag.readBlocks(tag.id, startBlock, endBlock);
715
867
  });
716
868
  }
717
869
  async function getSystemInfo2() {
718
- return await nfcService.withTechnology(nfcVTag.tech, nfcVTag.getSystemInfo);
870
+ return await NfcPrimitives.withTechnology(nfcVTag.tech, nfcVTag.getSystemInfo);
719
871
  }
720
872
 
721
873
  // src/nfc/namespace.ts
@@ -726,93 +878,78 @@ var nfc = {
726
878
  tag: { ...operations_exports3 }
727
879
  };
728
880
 
729
- // src/react/nfc-provider.tsx
881
+ // src/react/use-nfc-tech.ts
730
882
  var import_react = require("react");
731
- var import_jsx_runtime = require("react/jsx-runtime");
732
- var NfcContext = (0, import_react.createContext)(null);
733
- function NfcProvider({ children }) {
734
- const [state, setState] = (0, import_react.useState)(nfcService.getState());
735
- (0, import_react.useEffect)(() => {
736
- const unsubscribe = nfcService.subscribe(setState);
737
- return unsubscribe;
738
- }, []);
739
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NfcContext.Provider, { value: { state, service: nfcService }, children });
740
- }
741
- function useNfcContext() {
742
- const ctx = (0, import_react.useContext)(NfcContext);
743
- if (!ctx) throw new Error("useNfcContext must be inside <NfcProvider>");
744
- return ctx;
883
+ function useNfcTech(tech3, withTechnology, afterTechnology, options) {
884
+ const startTech = (0, import_react.useCallback)(() => {
885
+ nfcService.startTech(tech3, withTechnology, afterTechnology, options || {}).catch(console.error);
886
+ }, [tech3, withTechnology, afterTechnology, options]);
887
+ return { startTech };
745
888
  }
746
889
 
747
- // src/react/use-nfc.ts
890
+ // src/react/use-nfc-tech-loop.ts
748
891
  var import_react2 = require("react");
749
- function useNfc(onTag, options) {
750
- (0, import_react2.useEffect)(() => {
751
- nfcService.startReader(
752
- async (tag) => {
753
- if (!tag.id) return;
754
- onTag(tag.id);
755
- },
756
- { cooldownMs: options == null ? void 0 : options.cooldownMs }
892
+ function useNfcTechLoop(tech3, withTechnology, afterTechnology, options) {
893
+ const [isRunning, setIsRunning] = (0, import_react2.useState)(false);
894
+ const start = (0, import_react2.useCallback)(async () => {
895
+ await nfcService.startTechLoop(
896
+ tech3,
897
+ withTechnology,
898
+ afterTechnology,
899
+ options || {}
757
900
  );
901
+ setIsRunning(true);
902
+ }, [tech3, withTechnology, afterTechnology, options]);
903
+ const stop = (0, import_react2.useCallback)(async () => {
904
+ await nfcService.stop();
905
+ setIsRunning(false);
906
+ }, []);
907
+ (0, import_react2.useEffect)(() => {
758
908
  return () => {
759
- nfcService.stopReader();
909
+ nfcService.stop();
760
910
  };
761
- }, [onTag]);
911
+ }, []);
912
+ return { start, stop, isRunning };
762
913
  }
763
914
 
764
- // src/react/use-nfc-reader.ts
915
+ // src/react/use-nfc-tag-event.ts
765
916
  var import_react3 = require("react");
766
- function useNfcReader() {
767
- const start = (0, import_react3.useCallback)(
768
- (onTag, cooldownMs) => {
769
- nfcService.startReader(onTag, { cooldownMs });
770
- },
771
- []
772
- );
773
- const stop = (0, import_react3.useCallback)(() => {
774
- nfcService.stopReader();
775
- }, []);
776
- return { start, stop };
917
+ function useNfcTagEvent(onTag) {
918
+ const startTech = (0, import_react3.useCallback)(() => {
919
+ nfcService.startTagEvent(onTag).catch(console.error);
920
+ }, [onTag]);
921
+ return { startTech };
777
922
  }
778
923
 
779
- // src/react/use-nfc-state.ts
924
+ // src/react/use-nfc-tag-event-loop.ts
780
925
  var import_react4 = require("react");
781
- function useNfcState() {
782
- const [nfcState, setNfcState] = (0, import_react4.useState)(nfcService.getState());
783
- (0, import_react4.useEffect)(() => nfcService.subscribe(setNfcState), []);
784
- return nfcState;
785
- }
786
-
787
- // src/react/use-nfc-technology.ts
788
- var import_react_native_nfc_manager9 = __toESM(require("react-native-nfc-manager"));
789
- function useNfcTechnology() {
790
- async function writeNdef(records) {
791
- return nfcService.withTechnology(import_react_native_nfc_manager9.NfcTech.Ndef, async () => {
792
- const bytes = import_react_native_nfc_manager9.Ndef.encodeMessage(records);
793
- await import_react_native_nfc_manager9.default.ndefHandler.writeNdefMessage(bytes);
794
- });
795
- }
796
- async function runWithTech(tech3, fn) {
797
- return nfcService.withTechnology(tech3, fn);
798
- }
799
- return {
800
- writeNdef,
801
- runWithTech
802
- };
926
+ function useNfcTagEventLoop(onTag, options) {
927
+ const [isRunning, setIsRunning] = (0, import_react4.useState)(false);
928
+ const start = (0, import_react4.useCallback)(async () => {
929
+ await nfcService.startTagEventLoop(onTag, options);
930
+ setIsRunning(true);
931
+ }, [onTag, options]);
932
+ const stop = (0, import_react4.useCallback)(async () => {
933
+ await nfcService.stop();
934
+ setIsRunning(false);
935
+ }, []);
936
+ (0, import_react4.useEffect)(() => {
937
+ return () => {
938
+ nfcService.stop();
939
+ };
940
+ }, []);
941
+ return { start, stop, isRunning };
803
942
  }
804
943
  // Annotate the CommonJS export names for ESM import in node:
805
944
  0 && (module.exports = {
806
- NfcProvider,
807
945
  nfc,
808
946
  nfcNdefTag,
809
947
  nfcService,
810
948
  nfcTag,
811
949
  nfcVTag,
812
- useNfc,
813
- useNfcContext,
814
- useNfcReader,
815
- useNfcState,
816
- useNfcTechnology
950
+ useNfcTagEvent,
951
+ useNfcTagEventLoop,
952
+ useNfcTech,
953
+ useNfcTechLoop
817
954
  });
818
955
  //# sourceMappingURL=index.js.map