@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.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
|
|
141
|
+
import nfcManager2 from "react-native-nfc-manager";
|
|
354
142
|
async function getTag() {
|
|
355
|
-
const tagEvent = await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
785
|
+
import { Platform as Platform2 } from "react-native";
|
|
634
786
|
import { NfcTech as NfcTech2 } from "react-native-nfc-manager";
|
|
635
|
-
var tech2 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
694
|
-
import {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
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 {
|
|
718
|
-
function
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
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.
|
|
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-
|
|
749
|
-
import {
|
|
750
|
-
function
|
|
751
|
-
const
|
|
752
|
-
|
|
753
|
-
|
|
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-
|
|
757
|
-
import
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
return
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
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
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
useNfcTechnology
|
|
913
|
+
useNfcTagEvent,
|
|
914
|
+
useNfcTagEventLoop,
|
|
915
|
+
useNfcTech,
|
|
916
|
+
useNfcTechLoop
|
|
788
917
|
};
|
|
789
918
|
//# sourceMappingURL=index.mjs.map
|