import { NfcErrorType, } from "./definitions.js"; import { WebNfc } from "./web.js"; /** * Main NFC class that provides access to NFC functionality. * It automatically chooses the appropriate implementation for the current platform. */ export class Nfc { constructor() { this.listeners = new Map(); // Currently we only have the Web implementation this.implementation = new WebNfc(); // Set up status monitoring to track NFC availability this.monitorNfcStatus(); } /** * Internal method to monitor NFC status changes */ async monitorNfcStatus() { try { // Set up listener for NFC status changes from implementation await this.implementation.addListener("nfcStatusChanged", (status) => { // Propagate to our own listeners this.notifyListeners("nfcStatusChanged", status); }); } catch (error) { console.warn("Failed to set up NFC status monitoring:", error); } } /** * Check if NFC is enabled (Android) or available (iOS/Web). * @returns Promise resolving to an object with an `enabled` boolean property */ async isEnabled() { try { return await this.implementation.isEnabled(); } catch (error) { console.error("Error checking NFC status:", error); return { enabled: false }; } } /** * Open NFC settings (Android) or app settings (iOS) or shows guidance (Web). * This helps users enable NFC if it's disabled. */ async openSettings() { return this.implementation.openSettings(); } /** * Start scanning for NFC tags. * @param options Configuration options for the scan session */ async startScanSession(options) { var _a, _b, _c; try { return await this.implementation.startScanSession(options); } catch (error) { // Convert to a standardized error object if possible const nfcError = new Error(error.message || "Failed to start NFC scan"); if (((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes("not supported")) || error.name === "NotSupportedError") { nfcError.code = NfcErrorType.NOT_SUPPORTED; } else if (((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes("permission")) || error.name === "NotAllowedError") { nfcError.code = NfcErrorType.PERMISSION_DENIED; } else if ((_c = error.message) === null || _c === void 0 ? void 0 : _c.includes("not enabled")) { nfcError.code = NfcErrorType.NOT_ENABLED; } else { nfcError.code = NfcErrorType.UNEXPECTED_ERROR; } throw nfcError; } } /** * Stop the current NFC scan session. */ async stopScanSession() { return this.implementation.stopScanSession(); } /** * Write an NDEF message to an NFC tag. * @param options Object containing the NDEF message to write */ async write(options) { return this.implementation.write(options); } /** * Make an NFC tag read-only. * WARNING: This is a permanent operation that cannot be undone. */ async makeReadOnly() { return this.implementation.makeReadOnly(); } /** * Format an NFC tag, erasing its contents and preparing it for writing. */ async format() { return this.implementation.format(); } /** * Erase the contents of an NFC tag. */ async erase() { return this.implementation.erase(); } /** * Share NDEF data via NFC (Android only, not available on iOS or Web). * @param options Object containing the NDEF message to share */ async share(options) { return this.implementation.share(options); } /** * Stop sharing NDEF data via NFC (Android only). */ async stopSharing() { return this.implementation.stopSharing(); } async addListener(eventName, listenerFunc) { var _a; // Add to our internal listener registry if (!this.listeners.has(eventName)) { this.listeners.set(eventName, new Set()); } (_a = this.listeners.get(eventName)) === null || _a === void 0 ? void 0 : _a.add(listenerFunc); // Register with the implementation const handle = await this.implementation.addListener(eventName, listenerFunc); // Return a handle that will clean up properly return { remove: async () => { var _a; (_a = this.listeners.get(eventName)) === null || _a === void 0 ? void 0 : _a.delete(listenerFunc); return handle.remove(); }, }; } /** * Remove all event listeners registered for this plugin. */ async removeAllListeners() { // Clear our internal listener registry this.listeners.clear(); // Remove listeners from the implementation return this.implementation.removeAllListeners(); } /** * Internal method to notify listeners of events */ notifyListeners(eventName, data) { const listeners = this.listeners.get(eventName); if (listeners) { for (const listener of listeners) { try { listener(data); } catch (error) { console.error(`Error in ${eventName} listener:`, error); } } } } }