@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.mjs CHANGED
@@ -133,226 +133,14 @@ __export(operations_exports4, {
133
133
  });
134
134
  import nfcManager4 from "react-native-nfc-manager";
135
135
 
136
- // src/nfc/service.ts
137
- import { Platform as Platform2 } from "react-native";
138
- import nfcManager2, {
139
- NfcEvents
140
- } from "react-native-nfc-manager";
141
-
142
- // src/nfc/error.ts
143
- var NfcError = class extends Error {
144
- constructor(message) {
145
- super(`[NFC] ${message}`);
146
- }
147
- };
148
-
149
- // src/nfc/service.ts
150
- var NfcService = class {
151
- constructor() {
152
- this.state = { mode: "idle", tag: null };
153
- this.listeners = /* @__PURE__ */ new Set();
154
- this.isProcessingTag = false;
155
- this.currentCooldownMs = 1500;
156
- this.readerModeFlags_ANDROID = null;
157
- nfcManager2.start();
158
- }
159
- enableReaderMode_ANDROID(flags) {
160
- if (Platform2.OS !== "android") return;
161
- this.readerModeFlags_ANDROID = flags;
162
- }
163
- // -----------------------------
164
- // Internal state management
165
- // -----------------------------
166
- setState(partial) {
167
- this.state = { ...this.state, ...partial };
168
- for (const listener of this.listeners) listener(this.state);
169
- }
170
- getState() {
171
- return this.state;
172
- }
173
- subscribe(fn) {
174
- this.listeners.add(fn);
175
- fn(this.state);
176
- return () => {
177
- this.listeners.delete(fn);
178
- };
179
- }
180
- // -----------------------------
181
- // START READER (Soft Continuous Mode)
182
- // -----------------------------
183
- async startReader(onTag, options) {
184
- var _a;
185
- if (this.state.mode !== "idle") {
186
- console.warn(`[NFC] Cannot start reader while ${this.state.mode}`);
187
- return;
188
- }
189
- this.currentOnTag = onTag;
190
- this.currentCooldownMs = (_a = options == null ? void 0 : options.cooldownMs) != null ? _a : 1500;
191
- this.isProcessingTag = false;
192
- this.setState({ mode: "starting", tag: null });
193
- nfcManager2.setEventListener(
194
- NfcEvents.DiscoverTag,
195
- async (tag) => {
196
- var _a2;
197
- if (!tag) return;
198
- if (this.isProcessingTag) return;
199
- this.isProcessingTag = true;
200
- this.setState({ tag, mode: "active" });
201
- try {
202
- await ((_a2 = this.currentOnTag) == null ? void 0 : _a2.call(this, tag));
203
- } catch (err) {
204
- console.warn("[NFC] onTag handler error:", err);
205
- } finally {
206
- const cooldown = this.currentCooldownMs;
207
- if (this.cooldownTimer) {
208
- clearTimeout(this.cooldownTimer);
209
- }
210
- this.cooldownTimer = setTimeout(() => {
211
- this.isProcessingTag = false;
212
- this.setState({ tag: null });
213
- this.cooldownTimer = void 0;
214
- }, cooldown);
215
- }
216
- }
217
- );
218
- try {
219
- if (this.readerModeFlags_ANDROID) {
220
- await nfcManager2.registerTagEvent({
221
- isReaderModeEnabled: true,
222
- readerModeFlags: this.readerModeFlags_ANDROID
223
- });
224
- } else {
225
- await nfcManager2.registerTagEvent();
226
- }
227
- if (this.state.mode === "starting") {
228
- this.setState({ mode: "active" });
229
- }
230
- } catch (err) {
231
- console.warn("[NFC] startReader error:", err);
232
- this._resetReaderState();
233
- }
234
- }
235
- // -----------------------------
236
- // STOP READER (explicit only)
237
- // -----------------------------
238
- async stopReader() {
239
- if (["idle", "stopping"].includes(this.state.mode)) return;
240
- this.setState({ mode: "stopping" });
241
- nfcManager2.setEventListener(NfcEvents.DiscoverTag, () => {
242
- });
243
- if (this.cooldownTimer) {
244
- clearTimeout(this.cooldownTimer);
245
- this.cooldownTimer = void 0;
246
- }
247
- try {
248
- await nfcManager2.unregisterTagEvent();
249
- } catch (err) {
250
- console.warn("[NFC] unregisterTagEvent error:", err);
251
- }
252
- this._resetReaderState();
253
- }
254
- _resetReaderState() {
255
- if (this.cooldownTimer) {
256
- clearTimeout(this.cooldownTimer);
257
- this.cooldownTimer = void 0;
258
- }
259
- this.setState({ mode: "idle", tag: null });
260
- this.currentOnTag = void 0;
261
- this.isProcessingTag = false;
262
- }
263
- // -----------------------------
264
- // Technology sessions (NDEF, NfcV, etc.)
265
- // -----------------------------
266
- async withTechnology(tech3, handler) {
267
- if (this.state.mode === "technology") {
268
- throw new NfcError("Technology is already in use!");
269
- }
270
- if (this.readerModeFlags_ANDROID) {
271
- return this.withTechnologyReaderMode_ANDROID(
272
- tech3,
273
- handler,
274
- this.readerModeFlags_ANDROID
275
- );
276
- }
277
- const readerWasActive = ["starting", "active", "stopping"].includes(
278
- this.state.mode
279
- );
280
- const savedOnTag = this.currentOnTag;
281
- const savedCooldown = this.currentCooldownMs;
282
- if (readerWasActive) {
283
- await this.stopReader();
284
- }
285
- if (this.state.mode !== "idle") {
286
- throw new NfcError(
287
- `Cannot start technology session in mode ${this.state.mode}`
288
- );
289
- }
290
- this.setState({ mode: "technology" });
291
- try {
292
- await nfcManager2.requestTechnology(tech3, {
293
- alertMessage: "Hold near NFC tag"
294
- });
295
- const result = await handler();
296
- if (Platform2.OS === "ios") {
297
- await nfcManager2.setAlertMessageIOS("Success!");
298
- }
299
- return result;
300
- } catch (err) {
301
- const message = typeof err === "string" ? err : (err == null ? void 0 : err.message) || "Unknown NFC error";
302
- throw new NfcError(`withTechnology error: ${message}`);
303
- } finally {
304
- try {
305
- await nfcManager2.cancelTechnologyRequest();
306
- } catch {
307
- }
308
- this.setState({ mode: "idle", tag: null });
309
- if (readerWasActive) {
310
- try {
311
- await this.startReader(savedOnTag, { cooldownMs: savedCooldown });
312
- } catch (err) {
313
- console.warn(
314
- "[NFC] Failed to restart reader after tech session",
315
- err
316
- );
317
- }
318
- }
319
- }
320
- }
321
- async withTechnologyReaderMode_ANDROID(tech3, handler, flags) {
322
- const readerWasActive = ["starting", "active", "stopping"].includes(
323
- this.state.mode
324
- );
325
- this.isProcessingTag = true;
326
- this.setState({ mode: "technology" });
327
- try {
328
- await nfcManager2.requestTechnology(tech3, {
329
- isReaderModeEnabled: true,
330
- readerModeFlags: flags
331
- });
332
- return await handler();
333
- } catch (err) {
334
- const message = typeof err === "string" ? err : (err == null ? void 0 : err.message) || "Unknown NFC error";
335
- throw new NfcError(`withTechnologyReaderMode_ANDROID error: ${message}`);
336
- } finally {
337
- try {
338
- await nfcManager2.cancelTechnologyRequest();
339
- } catch {
340
- }
341
- this.isProcessingTag = false;
342
- this.setState({ mode: readerWasActive ? "active" : "idle" });
343
- }
344
- }
345
- };
346
- var nfcService = new NfcService();
347
-
348
136
  // src/nfc/tag/internal/operations.ts
349
137
  var operations_exports2 = {};
350
138
  __export(operations_exports2, {
351
139
  getTag: () => getTag
352
140
  });
353
- import nfcManager3 from "react-native-nfc-manager";
141
+ import nfcManager2 from "react-native-nfc-manager";
354
142
  async function getTag() {
355
- const tagEvent = await nfcManager3.getTag();
143
+ const tagEvent = await nfcManager2.getTag();
356
144
  if (!tagEvent) throw new Error("No tag detected");
357
145
  return tagEvent;
358
146
  }
@@ -367,8 +155,67 @@ var operations_exports3 = {};
367
155
  __export(operations_exports3, {
368
156
  getTag: () => getTag2
369
157
  });
158
+
159
+ // src/nfc/primitives.ts
160
+ import nfcManager3 from "react-native-nfc-manager";
161
+ var _NfcPrimitives = class _NfcPrimitives {
162
+ static async cleanTechnology() {
163
+ await _NfcPrimitives.stopTechnology();
164
+ _NfcPrimitives.isCancellingTechnology = false;
165
+ }
166
+ static async startTechnology(tech3, options) {
167
+ if (_NfcPrimitives.isRequestingTechnology) {
168
+ throw new Error("Technology already started");
169
+ }
170
+ _NfcPrimitives.isRequestingTechnology = true;
171
+ try {
172
+ console.log("Technology started");
173
+ await nfcManager3.requestTechnology(tech3, options);
174
+ } finally {
175
+ _NfcPrimitives.isRequestingTechnology = false;
176
+ }
177
+ }
178
+ static async stopTechnology() {
179
+ if (_NfcPrimitives.isCancellingTechnology) return;
180
+ _NfcPrimitives.isCancellingTechnology = true;
181
+ try {
182
+ await nfcManager3.cancelTechnologyRequest();
183
+ console.log("Technology stopped");
184
+ } catch (_e) {
185
+ } finally {
186
+ _NfcPrimitives.isCancellingTechnology = false;
187
+ }
188
+ }
189
+ static async withTechnology(tech3, callback, options) {
190
+ let res;
191
+ try {
192
+ await _NfcPrimitives.startTechnology(tech3, options);
193
+ res = await callback();
194
+ } finally {
195
+ await _NfcPrimitives.stopTechnology();
196
+ }
197
+ return res;
198
+ }
199
+ static async getTag() {
200
+ return await nfcManager3.getTag();
201
+ }
202
+ static async registerTagEvent(options) {
203
+ await nfcManager3.registerTagEvent(options);
204
+ }
205
+ static async unregisterTagEvent() {
206
+ await nfcManager3.unregisterTagEvent();
207
+ }
208
+ static setEventListener(event, handler) {
209
+ nfcManager3.setEventListener(event, handler);
210
+ }
211
+ };
212
+ _NfcPrimitives.isRequestingTechnology = false;
213
+ _NfcPrimitives.isCancellingTechnology = false;
214
+ var NfcPrimitives = _NfcPrimitives;
215
+
216
+ // src/nfc/tag/operations.ts
370
217
  async function getTag2(tech3) {
371
- return nfcService.withTechnology(tech3, nfcTag.getTag);
218
+ return NfcPrimitives.withTechnology(tech3, nfcTag.getTag);
372
219
  }
373
220
 
374
221
  // src/nfc/ndef/operations.ts
@@ -376,13 +223,13 @@ async function getStatus() {
376
223
  return await nfcManager4.ndefHandler.getNdefStatus();
377
224
  }
378
225
  async function readMessage2() {
379
- return await nfcService.withTechnology(
226
+ return await NfcPrimitives.withTechnology(
380
227
  nfcNdefTag.tech,
381
228
  nfcNdefTag.readMessage
382
229
  );
383
230
  }
384
231
  async function readFull() {
385
- return await nfcService.withTechnology(nfcNdefTag.tech, async () => {
232
+ return await NfcPrimitives.withTechnology(nfcNdefTag.tech, async () => {
386
233
  const tag = await nfcTag.getTag();
387
234
  const message = await nfcNdefTag.readMessage();
388
235
  return { message, tag };
@@ -392,7 +239,7 @@ async function write2(records) {
392
239
  if (!records || records.length === 0) {
393
240
  throw new NdefError("write: no NDEF records provided");
394
241
  }
395
- await nfcService.withTechnology(
242
+ await NfcPrimitives.withTechnology(
396
243
  nfcNdefTag.tech,
397
244
  async () => await nfcNdefTag.write(records)
398
245
  );
@@ -433,12 +280,317 @@ async function writeExternal(domain, type, payload, id) {
433
280
  await write2([rec]);
434
281
  }
435
282
  async function makeReadOnly() {
436
- await nfcService.withTechnology(
283
+ await NfcPrimitives.withTechnology(
437
284
  nfcNdefTag.tech,
438
285
  nfcManager4.ndefHandler.makeReadOnly
439
286
  );
440
287
  }
441
288
 
289
+ // src/nfc/service/state/index.ts
290
+ var NfcStateMachine = class {
291
+ constructor() {
292
+ this.state = "idle" /* IDLE */;
293
+ this.currentJob = null;
294
+ }
295
+ async transition(to, strategy) {
296
+ if (!this.currentJob) {
297
+ throw new Error("No current job");
298
+ }
299
+ if (!strategy.canHandle(this.currentJob)) {
300
+ throw new Error(
301
+ `Strategy ${strategy.constructor.name} cannot handle ${this.currentJob.type}`
302
+ );
303
+ }
304
+ console.log(`\u{1F504} ${this.state} \u2192 ${to}`);
305
+ this.state = to;
306
+ }
307
+ getState() {
308
+ return this.state;
309
+ }
310
+ setCurrentJob(job) {
311
+ this.currentJob = job;
312
+ }
313
+ async transitionToIdle() {
314
+ console.log("\u{1F504} Transitioning to idle");
315
+ this.state = "idle" /* IDLE */;
316
+ this.currentJob = null;
317
+ }
318
+ async stop() {
319
+ if (this.state === "idle" /* IDLE */) return;
320
+ if (!this.isLoopingState()) return;
321
+ console.log("\u{1F504} Transitioning to stopping");
322
+ this.state = "stopping" /* STOPPING */;
323
+ }
324
+ isLoopingState() {
325
+ return ["tech_loop" /* TECH_LOOP */, "tag_event_loop" /* TAG_EVENT_LOOP */].includes(this.state);
326
+ }
327
+ };
328
+
329
+ // src/nfc/error.ts
330
+ var NfcError = class extends Error {
331
+ constructor(message) {
332
+ super(`[NFC] ${message}`);
333
+ }
334
+ };
335
+
336
+ // src/nfc/service/strategies/error.ts
337
+ var NfcStrategyError = class extends NfcError {
338
+ constructor(message, strategy) {
339
+ super(`[${strategy}] ${message}`);
340
+ }
341
+ };
342
+
343
+ // src/nfc/service/strategies/tag-event.ts
344
+ import { NfcEvents } from "react-native-nfc-manager";
345
+ var TagEventStrategy = class {
346
+ canHandle(job) {
347
+ return job.type === "tag_event" /* TAG_EVENT */;
348
+ }
349
+ async execute(job, stateMachine) {
350
+ const { onTag, options } = job;
351
+ NfcPrimitives.setEventListener(NfcEvents.DiscoverTag, null);
352
+ try {
353
+ await NfcPrimitives.registerTagEvent(options);
354
+ } catch (err) {
355
+ NfcPrimitives.setEventListener(NfcEvents.DiscoverTag, null);
356
+ throw new NfcStrategyError(
357
+ `TagEvent registration failed: ${err.message}`,
358
+ this.constructor.name
359
+ );
360
+ }
361
+ return new Promise((resolve, reject) => {
362
+ let done = false;
363
+ const handler = async (tag) => {
364
+ if (done) return;
365
+ done = true;
366
+ try {
367
+ await onTag(tag);
368
+ resolve();
369
+ } catch (err) {
370
+ reject(
371
+ new NfcStrategyError(
372
+ `Tag processing failed: ${err.message}`,
373
+ this.constructor.name
374
+ )
375
+ );
376
+ } finally {
377
+ NfcPrimitives.setEventListener(NfcEvents.DiscoverTag, null);
378
+ try {
379
+ await NfcPrimitives.unregisterTagEvent();
380
+ } catch {
381
+ }
382
+ }
383
+ };
384
+ NfcPrimitives.setEventListener(NfcEvents.DiscoverTag, handler);
385
+ });
386
+ }
387
+ };
388
+
389
+ // src/nfc/service/strategies/tag-event-loop.ts
390
+ import { NfcEvents as NfcEvents2 } from "react-native-nfc-manager";
391
+ var TagEventLoopStrategy = class {
392
+ canHandle(job) {
393
+ return job.type === "tag_event_loop" /* TAG_EVENT_LOOP */;
394
+ }
395
+ async execute(job, stateMachine) {
396
+ const { onTag, options } = job;
397
+ let isProcessingTag = false;
398
+ let cooldownTimer;
399
+ const handleTagEvent = async (tag) => {
400
+ if (!tag || isProcessingTag) return;
401
+ isProcessingTag = true;
402
+ try {
403
+ await onTag(tag);
404
+ } catch (err) {
405
+ console.warn("[NFC] Tag processing failed:", err);
406
+ } finally {
407
+ isProcessingTag = false;
408
+ }
409
+ };
410
+ NfcPrimitives.setEventListener(NfcEvents2.DiscoverTag, handleTagEvent);
411
+ try {
412
+ await NfcPrimitives.registerTagEvent(options);
413
+ await new Promise((resolve) => {
414
+ const interval = setInterval(() => {
415
+ if (stateMachine.getState() === "stopping" /* STOPPING */) {
416
+ clearInterval(interval);
417
+ resolve();
418
+ }
419
+ }, 100);
420
+ });
421
+ } catch (err) {
422
+ throw new NfcStrategyError(
423
+ `TagEvent loop failed: ${err.message}`,
424
+ this.constructor.name
425
+ );
426
+ } finally {
427
+ NfcPrimitives.setEventListener(NfcEvents2.DiscoverTag, null);
428
+ await NfcPrimitives.unregisterTagEvent().catch(() => {
429
+ });
430
+ if (cooldownTimer) clearTimeout(cooldownTimer);
431
+ }
432
+ }
433
+ };
434
+
435
+ // src/nfc/service/strategies/tech.ts
436
+ var TechStrategy = class {
437
+ canHandle(job) {
438
+ return job.type === "tech" /* TECH */;
439
+ }
440
+ async execute(job, stateMachine) {
441
+ const { tech: tech3, withTechnology, afterTechnology, options } = job;
442
+ await NfcPrimitives.withTechnology(tech3, withTechnology, options);
443
+ if (afterTechnology) {
444
+ await afterTechnology();
445
+ }
446
+ }
447
+ };
448
+
449
+ // src/nfc/service/strategies/tech-loop.ts
450
+ var TechLoopStrategy = class {
451
+ canHandle(job) {
452
+ return job.type === "tech_loop" /* TECH_LOOP */;
453
+ }
454
+ async execute(job, stateMachine) {
455
+ const { tech: tech3, withTechnology, afterTechnology, options } = job;
456
+ while (true) {
457
+ if (stateMachine.getState() === "stopping" /* STOPPING */) break;
458
+ try {
459
+ await NfcPrimitives.withTechnology(tech3, withTechnology, options);
460
+ } catch (e) {
461
+ if (await handleStartTechError(e)) {
462
+ continue;
463
+ }
464
+ break;
465
+ }
466
+ if (afterTechnology) {
467
+ await afterTechnology();
468
+ }
469
+ }
470
+ }
471
+ };
472
+ async function handleStartTechError(e) {
473
+ if (e.message.includes("UserCancel")) {
474
+ console.log("withTechnology() Cancelled");
475
+ return true;
476
+ }
477
+ if (e.message === "Technology already started") {
478
+ console.warn("withTechnology() Already started");
479
+ await NfcPrimitives.stopTechnology();
480
+ return true;
481
+ }
482
+ console.error("withTechnology() failed", e.message);
483
+ return false;
484
+ }
485
+
486
+ // src/nfc/service/index.ts
487
+ var NfcService = class _NfcService {
488
+ constructor() {
489
+ this.strategies = [
490
+ new TagEventStrategy(),
491
+ new TagEventLoopStrategy(),
492
+ new TechStrategy(),
493
+ new TechLoopStrategy()
494
+ ];
495
+ this.stateMachine = new NfcStateMachine();
496
+ this.jobRetry = null;
497
+ this.isExecutingJobs = false;
498
+ }
499
+ static getInstance() {
500
+ if (!_NfcService.instance) _NfcService.instance = new _NfcService();
501
+ return _NfcService.instance;
502
+ }
503
+ async startTech(tech3, withTechnology, afterTechnology, options) {
504
+ const job = {
505
+ type: "tech" /* TECH */,
506
+ tech: tech3,
507
+ withTechnology,
508
+ afterTechnology,
509
+ options
510
+ };
511
+ await this.executeOrQueue(job);
512
+ }
513
+ async startTechLoop(tech3, withTechnology, afterTechnology, options) {
514
+ const job = {
515
+ type: "tech_loop" /* TECH_LOOP */,
516
+ tech: tech3,
517
+ withTechnology,
518
+ afterTechnology,
519
+ options
520
+ };
521
+ this.executeOrQueue(job);
522
+ }
523
+ async startTagEvent(onTag) {
524
+ const job = {
525
+ type: "tag_event" /* TAG_EVENT */,
526
+ onTag
527
+ };
528
+ await this.executeOrQueue(job);
529
+ }
530
+ async startTagEventLoop(onTag, options) {
531
+ const job = {
532
+ type: "tag_event_loop" /* TAG_EVENT_LOOP */,
533
+ onTag,
534
+ options
535
+ };
536
+ await this.executeOrQueue(job);
537
+ }
538
+ async stop() {
539
+ console.log("\u{1F6D1} Stopping NFC");
540
+ this.jobRetry = null;
541
+ await this.stateMachine.stop();
542
+ }
543
+ async executeOrQueue(job) {
544
+ const state = this.stateMachine.getState();
545
+ if (state === "stopping" /* STOPPING */) {
546
+ console.log("\u{1F504} Setting retry job:", job.type);
547
+ this.jobRetry = job;
548
+ return;
549
+ }
550
+ await this.executeJob(job);
551
+ }
552
+ async executeJob(job) {
553
+ if (this.isExecutingJobs) return;
554
+ this.isExecutingJobs = true;
555
+ let _nextJob = job;
556
+ while (_nextJob) {
557
+ const strategy = this.strategies.find((s) => s.canHandle(job));
558
+ if (!strategy) throw new Error(`No strategy for ${job.type}`);
559
+ this.stateMachine.setCurrentJob(job);
560
+ try {
561
+ const targetState = mapJobTypeToState(job.type);
562
+ await this.stateMachine.transition(targetState, strategy);
563
+ console.log(`\u{1F680} Starting ${job.type} via ${strategy.constructor.name}`);
564
+ await strategy.execute(job, this.stateMachine);
565
+ console.log(`\u2705 Completed ${job.type}`);
566
+ } catch (error) {
567
+ console.error(`\u274C ${job.type} failed:`, error);
568
+ throw error;
569
+ } finally {
570
+ await this.stateMachine.transitionToIdle();
571
+ if (this.jobRetry) {
572
+ console.log("\u{1F504} Retrying job:", this.jobRetry.type);
573
+ }
574
+ _nextJob = this.jobRetry;
575
+ }
576
+ }
577
+ this.isExecutingJobs = false;
578
+ }
579
+ };
580
+ function mapJobTypeToState(type) {
581
+ switch (type) {
582
+ case "tech" /* TECH */:
583
+ return "tech" /* TECH */;
584
+ case "tech_loop" /* TECH_LOOP */:
585
+ return "tech_loop" /* TECH_LOOP */;
586
+ case "tag_event" /* TAG_EVENT */:
587
+ return "tag_event" /* TAG_EVENT */;
588
+ case "tag_event_loop" /* TAG_EVENT_LOOP */:
589
+ return "tag_event_loop" /* TAG_EVENT_LOOP */;
590
+ }
591
+ }
592
+ var nfcService = NfcService.getInstance();
593
+
442
594
  // src/nfc/v/internal/operations.ts
443
595
  var operations_exports5 = {};
444
596
  __export(operations_exports5, {
@@ -630,9 +782,9 @@ async function getSystemInfo() {
630
782
  }
631
783
 
632
784
  // src/nfc/v/internal/tech.ts
633
- import { Platform as Platform3 } from "react-native";
785
+ import { Platform as Platform2 } from "react-native";
634
786
  import { NfcTech as NfcTech2 } from "react-native-nfc-manager";
635
- var tech2 = Platform3.OS === "ios" ? [NfcTech2.Iso15693IOS] : NfcTech2.NfcV;
787
+ var tech2 = Platform2.OS === "ios" ? [NfcTech2.Iso15693IOS] : [NfcTech2.NfcV];
636
788
 
637
789
  // src/nfc/v/internal/index.ts
638
790
  var nfcVTag = {
@@ -651,35 +803,35 @@ __export(operations_exports6, {
651
803
  writeBlocks: () => writeBlocks2
652
804
  });
653
805
  async function writeBlock2(blockNumber, data) {
654
- await nfcService.withTechnology(nfcVTag.tech, async () => {
806
+ await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
655
807
  const tag = await nfcTag.getTag();
656
808
  if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
657
809
  await nfcVTag.writeBlock(tag.id, blockNumber, data);
658
810
  });
659
811
  }
660
812
  async function writeBlocks2(blockNumber, data) {
661
- await nfcService.withTechnology(nfcVTag.tech, async () => {
813
+ await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
662
814
  const tag = await nfcTag.getTag();
663
815
  if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
664
816
  nfcVTag.writeBlocks(tag.id, blockNumber, data);
665
817
  });
666
818
  }
667
819
  async function readBlock2(blockNumber) {
668
- return await nfcService.withTechnology(nfcVTag.tech, async () => {
820
+ return await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
669
821
  const tag = await nfcTag.getTag();
670
822
  if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
671
823
  return await nfcVTag.readBlock(tag.id, blockNumber);
672
824
  });
673
825
  }
674
826
  async function readBlocks2(startBlock, endBlock) {
675
- return await nfcService.withTechnology(nfcVTag.tech, async () => {
827
+ return await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
676
828
  const tag = await nfcTag.getTag();
677
829
  if (!(tag == null ? void 0 : tag.id)) throw new Error("No NFC-V tag id detected");
678
830
  return await nfcVTag.readBlocks(tag.id, startBlock, endBlock);
679
831
  });
680
832
  }
681
833
  async function getSystemInfo2() {
682
- return await nfcService.withTechnology(nfcVTag.tech, nfcVTag.getSystemInfo);
834
+ return await NfcPrimitives.withTechnology(nfcVTag.tech, nfcVTag.getSystemInfo);
683
835
  }
684
836
 
685
837
  // src/nfc/namespace.ts
@@ -690,100 +842,77 @@ var nfc = {
690
842
  tag: { ...operations_exports3 }
691
843
  };
692
844
 
693
- // src/react/nfc-provider.tsx
694
- import {
695
- createContext,
696
- useContext,
697
- useEffect,
698
- useState
699
- } from "react";
700
- import { jsx } from "react/jsx-runtime";
701
- var NfcContext = createContext(null);
702
- function NfcProvider({ children }) {
703
- const [state, setState] = useState(nfcService.getState());
704
- useEffect(() => {
705
- const unsubscribe = nfcService.subscribe(setState);
706
- return unsubscribe;
707
- }, []);
708
- return /* @__PURE__ */ jsx(NfcContext.Provider, { value: { state, service: nfcService }, children });
709
- }
710
- function useNfcContext() {
711
- const ctx = useContext(NfcContext);
712
- if (!ctx) throw new Error("useNfcContext must be inside <NfcProvider>");
713
- return ctx;
845
+ // src/react/use-nfc-tech.ts
846
+ import { useCallback } from "react";
847
+ function useNfcTech(tech3, withTechnology, afterTechnology, options) {
848
+ const startTech = useCallback(() => {
849
+ nfcService.startTech(tech3, withTechnology, afterTechnology, options || {}).catch(console.error);
850
+ }, [tech3, withTechnology, afterTechnology, options]);
851
+ return { startTech };
714
852
  }
715
853
 
716
- // src/react/use-nfc.ts
717
- import { useEffect as useEffect2 } from "react";
718
- function useNfc(onTag, options) {
719
- useEffect2(() => {
720
- nfcService.startReader(
721
- async (tag) => {
722
- if (!tag.id) return;
723
- onTag(tag.id);
724
- },
725
- { cooldownMs: options == null ? void 0 : options.cooldownMs }
854
+ // src/react/use-nfc-tech-loop.ts
855
+ import { useCallback as useCallback2, useEffect, useState } from "react";
856
+ function useNfcTechLoop(tech3, withTechnology, afterTechnology, options) {
857
+ const [isRunning, setIsRunning] = useState(false);
858
+ const start = useCallback2(async () => {
859
+ await nfcService.startTechLoop(
860
+ tech3,
861
+ withTechnology,
862
+ afterTechnology,
863
+ options || {}
726
864
  );
865
+ setIsRunning(true);
866
+ }, [tech3, withTechnology, afterTechnology, options]);
867
+ const stop = useCallback2(async () => {
868
+ await nfcService.stop();
869
+ setIsRunning(false);
870
+ }, []);
871
+ useEffect(() => {
727
872
  return () => {
728
- nfcService.stopReader();
873
+ nfcService.stop();
729
874
  };
730
- }, [onTag]);
731
- }
732
-
733
- // src/react/use-nfc-reader.ts
734
- import { useCallback } from "react";
735
- function useNfcReader() {
736
- const start = useCallback(
737
- (onTag, cooldownMs) => {
738
- nfcService.startReader(onTag, { cooldownMs });
739
- },
740
- []
741
- );
742
- const stop = useCallback(() => {
743
- nfcService.stopReader();
744
875
  }, []);
745
- return { start, stop };
876
+ return { start, stop, isRunning };
746
877
  }
747
878
 
748
- // src/react/use-nfc-state.ts
749
- import { useEffect as useEffect3, useState as useState2 } from "react";
750
- function useNfcState() {
751
- const [nfcState, setNfcState] = useState2(nfcService.getState());
752
- useEffect3(() => nfcService.subscribe(setNfcState), []);
753
- return nfcState;
879
+ // src/react/use-nfc-tag-event.ts
880
+ import { useCallback as useCallback3 } from "react";
881
+ function useNfcTagEvent(onTag) {
882
+ const startTech = useCallback3(() => {
883
+ nfcService.startTagEvent(onTag).catch(console.error);
884
+ }, [onTag]);
885
+ return { startTech };
754
886
  }
755
887
 
756
- // src/react/use-nfc-technology.ts
757
- import NfcManager, {
758
- Ndef as Ndef3,
759
- NfcTech as NfcTech3
760
- } from "react-native-nfc-manager";
761
- function useNfcTechnology() {
762
- async function writeNdef(records) {
763
- return nfcService.withTechnology(NfcTech3.Ndef, async () => {
764
- const bytes = Ndef3.encodeMessage(records);
765
- await NfcManager.ndefHandler.writeNdefMessage(bytes);
766
- });
767
- }
768
- async function runWithTech(tech3, fn) {
769
- return nfcService.withTechnology(tech3, fn);
770
- }
771
- return {
772
- writeNdef,
773
- runWithTech
774
- };
888
+ // src/react/use-nfc-tag-event-loop.ts
889
+ import { useCallback as useCallback4, useEffect as useEffect2, useState as useState2 } from "react";
890
+ function useNfcTagEventLoop(onTag, options) {
891
+ const [isRunning, setIsRunning] = useState2(false);
892
+ const start = useCallback4(async () => {
893
+ await nfcService.startTagEventLoop(onTag, options);
894
+ setIsRunning(true);
895
+ }, [onTag, options]);
896
+ const stop = useCallback4(async () => {
897
+ await nfcService.stop();
898
+ setIsRunning(false);
899
+ }, []);
900
+ useEffect2(() => {
901
+ return () => {
902
+ nfcService.stop();
903
+ };
904
+ }, []);
905
+ return { start, stop, isRunning };
775
906
  }
776
907
  export {
777
- NfcProvider,
778
908
  nfc,
779
909
  nfcNdefTag,
780
910
  nfcService,
781
911
  nfcTag,
782
912
  nfcVTag,
783
- useNfc,
784
- useNfcContext,
785
- useNfcReader,
786
- useNfcState,
787
- useNfcTechnology
913
+ useNfcTagEvent,
914
+ useNfcTagEventLoop,
915
+ useNfcTech,
916
+ useNfcTechLoop
788
917
  };
789
918
  //# sourceMappingURL=index.mjs.map