@spencerls/react-native-nfc 1.0.10 → 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 +234 -94
- package/README.md +155 -150
- package/dist/index.d.mts +53 -62
- package/dist/index.d.ts +53 -62
- package/dist/index.js +440 -281
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +435 -281
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35,10 +35,10 @@ __export(index_exports, {
|
|
|
35
35
|
nfcService: () => nfcService,
|
|
36
36
|
nfcTag: () => nfcTag,
|
|
37
37
|
nfcVTag: () => nfcVTag,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
useNfcTagEvent: () => useNfcTagEvent,
|
|
39
|
+
useNfcTagEventLoop: () => useNfcTagEventLoop,
|
|
40
|
+
useNfcTech: () => useNfcTech,
|
|
41
|
+
useNfcTechLoop: () => useNfcTechLoop
|
|
42
42
|
});
|
|
43
43
|
module.exports = __toCommonJS(index_exports);
|
|
44
44
|
|
|
@@ -169,224 +169,14 @@ __export(operations_exports4, {
|
|
|
169
169
|
});
|
|
170
170
|
var import_react_native_nfc_manager6 = __toESM(require("react-native-nfc-manager"));
|
|
171
171
|
|
|
172
|
-
// src/nfc/service.ts
|
|
173
|
-
var import_react_native2 = require("react-native");
|
|
174
|
-
var import_react_native_nfc_manager4 = __toESM(require("react-native-nfc-manager"));
|
|
175
|
-
|
|
176
|
-
// src/nfc/error.ts
|
|
177
|
-
var NfcError = class extends Error {
|
|
178
|
-
constructor(message) {
|
|
179
|
-
super(`[NFC] ${message}`);
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
// src/nfc/service.ts
|
|
184
|
-
var NfcService = class {
|
|
185
|
-
constructor() {
|
|
186
|
-
this.state = { mode: "idle", tag: null };
|
|
187
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
188
|
-
this.isProcessingTag = false;
|
|
189
|
-
this.currentCooldownMs = 1500;
|
|
190
|
-
this.readerModeFlags_ANDROID = null;
|
|
191
|
-
import_react_native_nfc_manager4.default.start();
|
|
192
|
-
}
|
|
193
|
-
enableReaderMode_ANDROID(flags) {
|
|
194
|
-
if (import_react_native2.Platform.OS !== "android") return;
|
|
195
|
-
this.readerModeFlags_ANDROID = flags;
|
|
196
|
-
}
|
|
197
|
-
// -----------------------------
|
|
198
|
-
// Internal state management
|
|
199
|
-
// -----------------------------
|
|
200
|
-
setState(partial) {
|
|
201
|
-
this.state = { ...this.state, ...partial };
|
|
202
|
-
for (const listener of this.listeners) listener(this.state);
|
|
203
|
-
}
|
|
204
|
-
getState() {
|
|
205
|
-
return this.state;
|
|
206
|
-
}
|
|
207
|
-
subscribe(fn) {
|
|
208
|
-
this.listeners.add(fn);
|
|
209
|
-
fn(this.state);
|
|
210
|
-
return () => {
|
|
211
|
-
this.listeners.delete(fn);
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
// -----------------------------
|
|
215
|
-
// START READER (Soft Continuous Mode)
|
|
216
|
-
// -----------------------------
|
|
217
|
-
async startReader(onTag, options) {
|
|
218
|
-
var _a;
|
|
219
|
-
if (this.state.mode !== "idle") {
|
|
220
|
-
console.warn(`[NFC] Cannot start reader while ${this.state.mode}`);
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
this.currentOnTag = onTag;
|
|
224
|
-
this.currentCooldownMs = (_a = options == null ? void 0 : options.cooldownMs) != null ? _a : 1500;
|
|
225
|
-
this.isProcessingTag = false;
|
|
226
|
-
this.setState({ mode: "starting", tag: null });
|
|
227
|
-
import_react_native_nfc_manager4.default.setEventListener(
|
|
228
|
-
import_react_native_nfc_manager4.NfcEvents.DiscoverTag,
|
|
229
|
-
async (tag) => {
|
|
230
|
-
var _a2;
|
|
231
|
-
if (!tag) return;
|
|
232
|
-
if (this.isProcessingTag) return;
|
|
233
|
-
this.isProcessingTag = true;
|
|
234
|
-
this.setState({ tag, mode: "active" });
|
|
235
|
-
try {
|
|
236
|
-
await ((_a2 = this.currentOnTag) == null ? void 0 : _a2.call(this, tag));
|
|
237
|
-
} catch (err) {
|
|
238
|
-
console.warn("[NFC] onTag handler error:", err);
|
|
239
|
-
} finally {
|
|
240
|
-
const cooldown = this.currentCooldownMs;
|
|
241
|
-
if (this.cooldownTimer) {
|
|
242
|
-
clearTimeout(this.cooldownTimer);
|
|
243
|
-
}
|
|
244
|
-
this.cooldownTimer = setTimeout(() => {
|
|
245
|
-
this.isProcessingTag = false;
|
|
246
|
-
this.setState({ tag: null });
|
|
247
|
-
this.cooldownTimer = void 0;
|
|
248
|
-
}, cooldown);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
);
|
|
252
|
-
try {
|
|
253
|
-
if (this.readerModeFlags_ANDROID) {
|
|
254
|
-
await import_react_native_nfc_manager4.default.registerTagEvent({
|
|
255
|
-
isReaderModeEnabled: true,
|
|
256
|
-
readerModeFlags: this.readerModeFlags_ANDROID
|
|
257
|
-
});
|
|
258
|
-
} else {
|
|
259
|
-
await import_react_native_nfc_manager4.default.registerTagEvent();
|
|
260
|
-
}
|
|
261
|
-
if (this.state.mode === "starting") {
|
|
262
|
-
this.setState({ mode: "active" });
|
|
263
|
-
}
|
|
264
|
-
} catch (err) {
|
|
265
|
-
console.warn("[NFC] startReader error:", err);
|
|
266
|
-
this._resetReaderState();
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
// -----------------------------
|
|
270
|
-
// STOP READER (explicit only)
|
|
271
|
-
// -----------------------------
|
|
272
|
-
async stopReader() {
|
|
273
|
-
if (["idle", "stopping"].includes(this.state.mode)) return;
|
|
274
|
-
this.setState({ mode: "stopping" });
|
|
275
|
-
import_react_native_nfc_manager4.default.setEventListener(import_react_native_nfc_manager4.NfcEvents.DiscoverTag, () => {
|
|
276
|
-
});
|
|
277
|
-
if (this.cooldownTimer) {
|
|
278
|
-
clearTimeout(this.cooldownTimer);
|
|
279
|
-
this.cooldownTimer = void 0;
|
|
280
|
-
}
|
|
281
|
-
try {
|
|
282
|
-
await import_react_native_nfc_manager4.default.unregisterTagEvent();
|
|
283
|
-
} catch (err) {
|
|
284
|
-
console.warn("[NFC] unregisterTagEvent error:", err);
|
|
285
|
-
}
|
|
286
|
-
this._resetReaderState();
|
|
287
|
-
}
|
|
288
|
-
_resetReaderState() {
|
|
289
|
-
if (this.cooldownTimer) {
|
|
290
|
-
clearTimeout(this.cooldownTimer);
|
|
291
|
-
this.cooldownTimer = void 0;
|
|
292
|
-
}
|
|
293
|
-
this.setState({ mode: "idle", tag: null });
|
|
294
|
-
this.currentOnTag = void 0;
|
|
295
|
-
this.isProcessingTag = false;
|
|
296
|
-
}
|
|
297
|
-
// -----------------------------
|
|
298
|
-
// Technology sessions (NDEF, NfcV, etc.)
|
|
299
|
-
// -----------------------------
|
|
300
|
-
async withTechnology(tech3, handler) {
|
|
301
|
-
if (this.state.mode === "technology") {
|
|
302
|
-
throw new NfcError("Technology is already in use!");
|
|
303
|
-
}
|
|
304
|
-
if (this.readerModeFlags_ANDROID) {
|
|
305
|
-
return this.withTechnologyReaderMode_ANDROID(
|
|
306
|
-
tech3,
|
|
307
|
-
handler,
|
|
308
|
-
this.readerModeFlags_ANDROID
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
const readerWasActive = ["starting", "active", "stopping"].includes(
|
|
312
|
-
this.state.mode
|
|
313
|
-
);
|
|
314
|
-
const savedOnTag = this.currentOnTag;
|
|
315
|
-
const savedCooldown = this.currentCooldownMs;
|
|
316
|
-
if (readerWasActive) {
|
|
317
|
-
await this.stopReader();
|
|
318
|
-
}
|
|
319
|
-
if (this.state.mode !== "idle") {
|
|
320
|
-
throw new NfcError(
|
|
321
|
-
`Cannot start technology session in mode ${this.state.mode}`
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
this.setState({ mode: "technology" });
|
|
325
|
-
try {
|
|
326
|
-
await import_react_native_nfc_manager4.default.requestTechnology(tech3, {
|
|
327
|
-
alertMessage: "Hold near NFC tag"
|
|
328
|
-
});
|
|
329
|
-
const result = await handler();
|
|
330
|
-
if (import_react_native2.Platform.OS === "ios") {
|
|
331
|
-
await import_react_native_nfc_manager4.default.setAlertMessageIOS("Success!");
|
|
332
|
-
}
|
|
333
|
-
return result;
|
|
334
|
-
} catch (err) {
|
|
335
|
-
const message = typeof err === "string" ? err : (err == null ? void 0 : err.message) || "Unknown NFC error";
|
|
336
|
-
throw new NfcError(`withTechnology error: ${message}`);
|
|
337
|
-
} finally {
|
|
338
|
-
try {
|
|
339
|
-
await import_react_native_nfc_manager4.default.cancelTechnologyRequest();
|
|
340
|
-
} catch {
|
|
341
|
-
}
|
|
342
|
-
this.setState({ mode: "idle", tag: null });
|
|
343
|
-
if (readerWasActive) {
|
|
344
|
-
try {
|
|
345
|
-
await this.startReader(savedOnTag, { cooldownMs: savedCooldown });
|
|
346
|
-
} catch (err) {
|
|
347
|
-
console.warn(
|
|
348
|
-
"[NFC] Failed to restart reader after tech session",
|
|
349
|
-
err
|
|
350
|
-
);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
async withTechnologyReaderMode_ANDROID(tech3, handler, flags) {
|
|
356
|
-
const readerWasActive = ["starting", "active", "stopping"].includes(
|
|
357
|
-
this.state.mode
|
|
358
|
-
);
|
|
359
|
-
this.isProcessingTag = true;
|
|
360
|
-
this.setState({ mode: "technology" });
|
|
361
|
-
try {
|
|
362
|
-
await import_react_native_nfc_manager4.default.requestTechnology(tech3, {
|
|
363
|
-
isReaderModeEnabled: true,
|
|
364
|
-
readerModeFlags: flags
|
|
365
|
-
});
|
|
366
|
-
return await handler();
|
|
367
|
-
} catch (err) {
|
|
368
|
-
const message = typeof err === "string" ? err : (err == null ? void 0 : err.message) || "Unknown NFC error";
|
|
369
|
-
throw new NfcError(`withTechnologyReaderMode_ANDROID error: ${message}`);
|
|
370
|
-
} finally {
|
|
371
|
-
try {
|
|
372
|
-
await import_react_native_nfc_manager4.default.cancelTechnologyRequest();
|
|
373
|
-
} catch {
|
|
374
|
-
}
|
|
375
|
-
this.isProcessingTag = false;
|
|
376
|
-
this.setState({ mode: readerWasActive ? "active" : "idle" });
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
};
|
|
380
|
-
var nfcService = new NfcService();
|
|
381
|
-
|
|
382
172
|
// src/nfc/tag/internal/operations.ts
|
|
383
173
|
var operations_exports2 = {};
|
|
384
174
|
__export(operations_exports2, {
|
|
385
175
|
getTag: () => getTag
|
|
386
176
|
});
|
|
387
|
-
var
|
|
177
|
+
var import_react_native_nfc_manager4 = __toESM(require("react-native-nfc-manager"));
|
|
388
178
|
async function getTag() {
|
|
389
|
-
const tagEvent = await
|
|
179
|
+
const tagEvent = await import_react_native_nfc_manager4.default.getTag();
|
|
390
180
|
if (!tagEvent) throw new Error("No tag detected");
|
|
391
181
|
return tagEvent;
|
|
392
182
|
}
|
|
@@ -401,8 +191,67 @@ var operations_exports3 = {};
|
|
|
401
191
|
__export(operations_exports3, {
|
|
402
192
|
getTag: () => getTag2
|
|
403
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
|
|
404
253
|
async function getTag2(tech3) {
|
|
405
|
-
return
|
|
254
|
+
return NfcPrimitives.withTechnology(tech3, nfcTag.getTag);
|
|
406
255
|
}
|
|
407
256
|
|
|
408
257
|
// src/nfc/ndef/operations.ts
|
|
@@ -410,13 +259,13 @@ async function getStatus() {
|
|
|
410
259
|
return await import_react_native_nfc_manager6.default.ndefHandler.getNdefStatus();
|
|
411
260
|
}
|
|
412
261
|
async function readMessage2() {
|
|
413
|
-
return await
|
|
262
|
+
return await NfcPrimitives.withTechnology(
|
|
414
263
|
nfcNdefTag.tech,
|
|
415
264
|
nfcNdefTag.readMessage
|
|
416
265
|
);
|
|
417
266
|
}
|
|
418
267
|
async function readFull() {
|
|
419
|
-
return await
|
|
268
|
+
return await NfcPrimitives.withTechnology(nfcNdefTag.tech, async () => {
|
|
420
269
|
const tag = await nfcTag.getTag();
|
|
421
270
|
const message = await nfcNdefTag.readMessage();
|
|
422
271
|
return { message, tag };
|
|
@@ -426,7 +275,7 @@ async function write2(records) {
|
|
|
426
275
|
if (!records || records.length === 0) {
|
|
427
276
|
throw new NdefError("write: no NDEF records provided");
|
|
428
277
|
}
|
|
429
|
-
await
|
|
278
|
+
await NfcPrimitives.withTechnology(
|
|
430
279
|
nfcNdefTag.tech,
|
|
431
280
|
async () => await nfcNdefTag.write(records)
|
|
432
281
|
);
|
|
@@ -467,12 +316,317 @@ async function writeExternal(domain, type, payload, id) {
|
|
|
467
316
|
await write2([rec]);
|
|
468
317
|
}
|
|
469
318
|
async function makeReadOnly() {
|
|
470
|
-
await
|
|
319
|
+
await NfcPrimitives.withTechnology(
|
|
471
320
|
nfcNdefTag.tech,
|
|
472
321
|
import_react_native_nfc_manager6.default.ndefHandler.makeReadOnly
|
|
473
322
|
);
|
|
474
323
|
}
|
|
475
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
|
+
|
|
476
630
|
// src/nfc/v/internal/operations.ts
|
|
477
631
|
var operations_exports5 = {};
|
|
478
632
|
__export(operations_exports5, {
|
|
@@ -483,7 +637,7 @@ __export(operations_exports5, {
|
|
|
483
637
|
writeBlock: () => writeBlock,
|
|
484
638
|
writeBlocks: () => writeBlocks
|
|
485
639
|
});
|
|
486
|
-
var
|
|
640
|
+
var import_react_native_nfc_manager9 = __toESM(require("react-native-nfc-manager"));
|
|
487
641
|
|
|
488
642
|
// src/nfc/v/error.ts
|
|
489
643
|
var VError = class extends Error {
|
|
@@ -624,7 +778,7 @@ function detectManufacturer(uid) {
|
|
|
624
778
|
|
|
625
779
|
// src/nfc/v/internal/operations.ts
|
|
626
780
|
async function transceive(bytes) {
|
|
627
|
-
return await
|
|
781
|
+
return await import_react_native_nfc_manager9.default.nfcVHandler.transceive(bytes);
|
|
628
782
|
}
|
|
629
783
|
async function readBlock(tagId, blockNumber) {
|
|
630
784
|
const uid = reverseUid(tagId);
|
|
@@ -664,9 +818,9 @@ async function getSystemInfo() {
|
|
|
664
818
|
}
|
|
665
819
|
|
|
666
820
|
// src/nfc/v/internal/tech.ts
|
|
667
|
-
var
|
|
668
|
-
var
|
|
669
|
-
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];
|
|
670
824
|
|
|
671
825
|
// src/nfc/v/internal/index.ts
|
|
672
826
|
var nfcVTag = {
|
|
@@ -685,35 +839,35 @@ __export(operations_exports6, {
|
|
|
685
839
|
writeBlocks: () => writeBlocks2
|
|
686
840
|
});
|
|
687
841
|
async function writeBlock2(blockNumber, data) {
|
|
688
|
-
await
|
|
842
|
+
await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
|
|
689
843
|
const tag = await nfcTag.getTag();
|
|
690
844
|
if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
|
|
691
845
|
await nfcVTag.writeBlock(tag.id, blockNumber, data);
|
|
692
846
|
});
|
|
693
847
|
}
|
|
694
848
|
async function writeBlocks2(blockNumber, data) {
|
|
695
|
-
await
|
|
849
|
+
await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
|
|
696
850
|
const tag = await nfcTag.getTag();
|
|
697
851
|
if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
|
|
698
852
|
nfcVTag.writeBlocks(tag.id, blockNumber, data);
|
|
699
853
|
});
|
|
700
854
|
}
|
|
701
855
|
async function readBlock2(blockNumber) {
|
|
702
|
-
return await
|
|
856
|
+
return await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
|
|
703
857
|
const tag = await nfcTag.getTag();
|
|
704
858
|
if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
|
|
705
859
|
return await nfcVTag.readBlock(tag.id, blockNumber);
|
|
706
860
|
});
|
|
707
861
|
}
|
|
708
862
|
async function readBlocks2(startBlock, endBlock) {
|
|
709
|
-
return await
|
|
863
|
+
return await NfcPrimitives.withTechnology(nfcVTag.tech, async () => {
|
|
710
864
|
const tag = await nfcTag.getTag();
|
|
711
865
|
if (!(tag == null ? void 0 : tag.id)) throw new Error("No NFC-V tag id detected");
|
|
712
866
|
return await nfcVTag.readBlocks(tag.id, startBlock, endBlock);
|
|
713
867
|
});
|
|
714
868
|
}
|
|
715
869
|
async function getSystemInfo2() {
|
|
716
|
-
return await
|
|
870
|
+
return await NfcPrimitives.withTechnology(nfcVTag.tech, nfcVTag.getSystemInfo);
|
|
717
871
|
}
|
|
718
872
|
|
|
719
873
|
// src/nfc/namespace.ts
|
|
@@ -724,62 +878,67 @@ var nfc = {
|
|
|
724
878
|
tag: { ...operations_exports3 }
|
|
725
879
|
};
|
|
726
880
|
|
|
727
|
-
// src/react/use-nfc.ts
|
|
881
|
+
// src/react/use-nfc-tech.ts
|
|
728
882
|
var import_react = require("react");
|
|
729
|
-
function
|
|
730
|
-
(0, import_react.
|
|
731
|
-
nfcService.
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
onTag(tag.id);
|
|
735
|
-
},
|
|
736
|
-
{ cooldownMs: options == null ? void 0 : options.cooldownMs }
|
|
737
|
-
);
|
|
738
|
-
return () => {
|
|
739
|
-
nfcService.stopReader();
|
|
740
|
-
};
|
|
741
|
-
}, [onTag]);
|
|
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 };
|
|
742
888
|
}
|
|
743
889
|
|
|
744
|
-
// src/react/use-nfc-
|
|
890
|
+
// src/react/use-nfc-tech-loop.ts
|
|
745
891
|
var import_react2 = require("react");
|
|
746
|
-
function
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
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 || {}
|
|
900
|
+
);
|
|
901
|
+
setIsRunning(true);
|
|
902
|
+
}, [tech3, withTechnology, afterTechnology, options]);
|
|
903
|
+
const stop = (0, import_react2.useCallback)(async () => {
|
|
904
|
+
await nfcService.stop();
|
|
905
|
+
setIsRunning(false);
|
|
755
906
|
}, []);
|
|
756
|
-
|
|
907
|
+
(0, import_react2.useEffect)(() => {
|
|
908
|
+
return () => {
|
|
909
|
+
nfcService.stop();
|
|
910
|
+
};
|
|
911
|
+
}, []);
|
|
912
|
+
return { start, stop, isRunning };
|
|
757
913
|
}
|
|
758
914
|
|
|
759
|
-
// src/react/use-nfc-
|
|
915
|
+
// src/react/use-nfc-tag-event.ts
|
|
760
916
|
var import_react3 = require("react");
|
|
761
|
-
function
|
|
762
|
-
const
|
|
763
|
-
|
|
764
|
-
|
|
917
|
+
function useNfcTagEvent(onTag) {
|
|
918
|
+
const startTech = (0, import_react3.useCallback)(() => {
|
|
919
|
+
nfcService.startTagEvent(onTag).catch(console.error);
|
|
920
|
+
}, [onTag]);
|
|
921
|
+
return { startTech };
|
|
765
922
|
}
|
|
766
923
|
|
|
767
|
-
// src/react/use-nfc-
|
|
768
|
-
var
|
|
769
|
-
function
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
924
|
+
// src/react/use-nfc-tag-event-loop.ts
|
|
925
|
+
var import_react4 = require("react");
|
|
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 };
|
|
783
942
|
}
|
|
784
943
|
// Annotate the CommonJS export names for ESM import in node:
|
|
785
944
|
0 && (module.exports = {
|
|
@@ -788,9 +947,9 @@ function useNfcTechnology() {
|
|
|
788
947
|
nfcService,
|
|
789
948
|
nfcTag,
|
|
790
949
|
nfcVTag,
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
950
|
+
useNfcTagEvent,
|
|
951
|
+
useNfcTagEventLoop,
|
|
952
|
+
useNfcTech,
|
|
953
|
+
useNfcTechLoop
|
|
795
954
|
});
|
|
796
955
|
//# sourceMappingURL=index.js.map
|