@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/API.md +231 -104
- package/README.md +155 -166
- package/dist/index.d.mts +53 -71
- package/dist/index.d.ts +53 -71
- package/dist/index.js +437 -300
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +433 -304
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
|
177
|
+
var import_react_native_nfc_manager4 = __toESM(require("react-native-nfc-manager"));
|
|
390
178
|
async function getTag() {
|
|
391
|
-
const tagEvent = await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
670
|
-
var
|
|
671
|
-
var tech2 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
881
|
+
// src/react/use-nfc-tech.ts
|
|
730
882
|
var import_react = require("react");
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
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
|
|
750
|
-
(0, import_react2.
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
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.
|
|
909
|
+
nfcService.stop();
|
|
760
910
|
};
|
|
761
|
-
}, [
|
|
911
|
+
}, []);
|
|
912
|
+
return { start, stop, isRunning };
|
|
762
913
|
}
|
|
763
914
|
|
|
764
|
-
// src/react/use-nfc-
|
|
915
|
+
// src/react/use-nfc-tag-event.ts
|
|
765
916
|
var import_react3 = require("react");
|
|
766
|
-
function
|
|
767
|
-
const
|
|
768
|
-
(onTag
|
|
769
|
-
|
|
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-
|
|
924
|
+
// src/react/use-nfc-tag-event-loop.ts
|
|
780
925
|
var import_react4 = require("react");
|
|
781
|
-
function
|
|
782
|
-
const [
|
|
783
|
-
(0, import_react4.
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
|
|
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
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
useNfcTechnology
|
|
950
|
+
useNfcTagEvent,
|
|
951
|
+
useNfcTagEventLoop,
|
|
952
|
+
useNfcTech,
|
|
953
|
+
useNfcTechLoop
|
|
817
954
|
});
|
|
818
955
|
//# sourceMappingURL=index.js.map
|