{"_id":"@4demar/icard-electron-sdk","_rev":"2-7ec575054496c033f981f2ee5e8e2d41","name":"@4demar/icard-electron-sdk","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@4demar/icard-electron-sdk","version":"0.1.0","keywords":["rfid","chafon","icard","uhf","ble","electron","web-bluetooth","4demar"],"author":{"name":"Ademar de Souza Novaes Junior"},"license":"UNLICENSED","_id":"@4demar/icard-electron-sdk@0.1.0","maintainers":[{"name":"4demar","email":"junioor.aguia@gmail.com"}],"homepage":"https://github.com/4demar/icard-electron-sdk#readme","bugs":{"url":"https://github.com/4demar/icard-electron-sdk/issues"},"dist":{"shasum":"f8424da64e06fbd5a6a6050037df185f9d2cc615","tarball":"https://registry.npmjs.org/@4demar/icard-electron-sdk/-/icard-electron-sdk-0.1.0.tgz","fileCount":2,"integrity":"sha512-CWCOVDWV8tDbDKjAYxp1cutCkmsvkz/Cs4NJVDG1zWRkGejLmX5IHITRfGT9GXy62gczqADYT1Mhrm+ERBVRuw==","signatures":[{"sig":"MEYCIQD+oDZEMqLaDnOdQLpcdesDXn7gdeWwHmJdu52VZsC0UQIhALcbaWKG2TSyaOwmXihKBb4aPrZP5o1XvbJVFfxqLLGg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":8149},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"431eceb292d464d6d7b8e277ec9d6f5e277b30af","scripts":{"build":"tsc -p tsconfig.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"4demar","email":"junioor.aguia@gmail.com"},"repository":{"url":"git+https://github.com/4demar/icard-electron-sdk.git","type":"git"},"_npmVersion":"10.8.2","description":"SDK TypeScript do leitor i-card (Chafon UHF RFID via BLE) para aplicações React + Electron usando Web Bluetooth.","directories":{},"_nodeVersion":"20.19.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0","@types/web-bluetooth":"^0.0.20"},"_npmOperationalInternal":{"tmp":"tmp/icard-electron-sdk_0.1.0_1786031632228_0.7112946019696325","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@4demar/icard-electron-sdk","version":"0.1.1","description":"SDK TypeScript do leitor i-card (Chafon UHF RFID via BLE) para aplicações React + Electron usando Web Bluetooth.","type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"tsc -p tsconfig.json","prepublishOnly":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/4demar/icard-electron-sdk.git"},"publishConfig":{"registry":"https://registry.npmjs.org/","access":"public"},"keywords":["rfid","chafon","icard","uhf","ble","electron","web-bluetooth","4demar"],"author":{"name":"Ademar de Souza Novaes Junior"},"license":"UNLICENSED","devDependencies":{"typescript":"^5.4.0","@types/web-bluetooth":"^0.0.20"},"_id":"@4demar/icard-electron-sdk@0.1.1","gitHead":"8f5b0600d5c2e4020e449f7836d5e9b133cb134d","bugs":{"url":"https://github.com/4demar/icard-electron-sdk/issues"},"homepage":"https://github.com/4demar/icard-electron-sdk#readme","_nodeVersion":"20.19.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-H9xyWNDKdHBnIDHcjnKK+weeNT3HNuAFnTgHHsrK5/dyt8B1JD1qi1ldMBza8esmvWNW23v4zzM5xOrjiFJstg==","shasum":"293428bdb8042bd533e315de1be277ff426b5ef1","tarball":"https://registry.npmjs.org/@4demar/icard-electron-sdk/-/icard-electron-sdk-0.1.1.tgz","fileCount":2,"unpackedSize":7653,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQChrocOUj/zX0jqC29XunzAyj4gTNdmo0OZVNK/ZY96pgIgcXLrTCRnKymReDdCRAMUUULhlkndWIssnii1vYTXKww="}]},"_npmUser":{"name":"4demar","email":"junioor.aguia@gmail.com"},"directories":{},"maintainers":[{"name":"4demar","email":"junioor.aguia@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/icard-electron-sdk_0.1.1_1786032053640_0.5209997688203045"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-06T15:53:52.070Z","modified":"2026-08-06T16:00:53.923Z","0.1.0":"2026-08-06T15:53:52.371Z","0.1.1":"2026-08-06T16:00:53.785Z"},"bugs":{"url":"https://github.com/4demar/icard-electron-sdk/issues"},"author":{"name":"Ademar de Souza Novaes Junior"},"license":"UNLICENSED","homepage":"https://github.com/4demar/icard-electron-sdk#readme","keywords":["rfid","chafon","icard","uhf","ble","electron","web-bluetooth","4demar"],"repository":{"type":"git","url":"git+https://github.com/4demar/icard-electron-sdk.git"},"description":"SDK TypeScript do leitor i-card (Chafon UHF RFID via BLE) para aplicações React + Electron usando Web Bluetooth.","maintainers":[{"name":"4demar","email":"junioor.aguia@gmail.com"}],"readme":"# @4demar/icard-electron-sdk\r\n\r\nSDK TypeScript do leitor **i-card (Chafon UHF RFID via BLE)** para aplicações **React + Electron**.\r\n\r\nUsa **Web Bluetooth** (`navigator.bluetooth`) no processo renderer do Electron, mantendo o mesmo\r\nprotocolo de bytes do reader Chafon (serviço BLE `ffe0`, característica `ffe1`, CRC-16 polinômio\r\n`0x8408`).\r\n\r\n---\r\n\r\n## Instalação\r\n\r\n```bash\r\nnpm install @4demar/icard-electron-sdk\r\n```\r\n\r\n---\r\n\r\n## Pré-requisito obrigatório (Electron)\r\n\r\n`navigator.bluetooth` roda no **processo renderer**, mas o Electron **não abre o seletor de\r\ndispositivos sozinho**. É obrigatório tratar o evento `select-bluetooth-device` no processo **main**.\r\nSem isso, `ICardReader.connect()` nunca resolve.\r\n\r\nNo `main.ts`, após criar a `BrowserWindow`:\r\n\r\n```ts\r\nimport { BrowserWindow } from 'electron';\r\n\r\nconst win = new BrowserWindow({ /* ... */ });\r\n\r\n// Trata a seleção de dispositivo BLE.\r\nwin.webContents.on('select-bluetooth-device', (event, devices, callback) => {\r\n  event.preventDefault();\r\n\r\n  // Estratégia simples: conecta no primeiro reader com nome.\r\n  // Para uma UI de seleção, envie `devices` ao renderer via IPC.\r\n  const reader = devices.find((d) => d.deviceName && d.deviceName.length > 0);\r\n  if (reader) {\r\n    callback(reader.deviceId);\r\n  }\r\n  // Se a lista estiver incompleta, o evento é reemitido com novos devices.\r\n});\r\n\r\n// Concede permissões de Bluetooth.\r\nwin.webContents.session.setPermissionRequestHandler((_wc, _perm, cb) => cb(true));\r\nwin.webContents.session.setPermissionCheckHandler(() => true);\r\n```\r\n\r\n> No Windows, o rádio Bluetooth precisa estar ligado no SO.\r\n\r\n---\r\n\r\n## Uso básico (React + TypeScript)\r\n\r\n```tsx\r\nimport { useRef, useState } from 'react';\r\nimport { ICardReader } from '@4demar/icard-electron-sdk';\r\n\r\nexport function LeituraRFID() {\r\n  const readerRef = useRef<ICardReader | null>(null);\r\n  const [tags, setTags] = useState<Set<string>>(new Set());\r\n  const [conectado, setConectado] = useState(false);\r\n\r\n  async function conectar() {\r\n    const reader = new ICardReader();\r\n    readerRef.current = reader;\r\n\r\n    // DEVE ser chamado a partir de um clique (gesto do usuário).\r\n    const nome = await reader.connect();\r\n    console.log('Conectado a', nome);\r\n\r\n    // Aplica a configuração padrão.\r\n    await reader.setPower(30);\r\n    await reader.setInventoryScanTime(50); // 50 * 100ms = 5s\r\n    await reader.setRegion(15, 0);         // região Brasil\r\n\r\n    reader.onDisconnected(() => setConectado(false));\r\n    setConectado(true);\r\n\r\n    // Inventário contínuo.\r\n    await reader.scan((epcs) => {\r\n      setTags((prev) => {\r\n        const next = new Set(prev);\r\n        epcs.filter((e) => e.startsWith('30')).forEach((e) => next.add(e));\r\n        return next;\r\n      });\r\n    });\r\n  }\r\n\r\n  function parar() {\r\n    readerRef.current?.stopScan();\r\n  }\r\n\r\n  function desconectar() {\r\n    readerRef.current?.disconnect();\r\n    setConectado(false);\r\n  }\r\n\r\n  return (\r\n    <div>\r\n      <button onClick={conectar} disabled={conectado}>Conectar e ler</button>\r\n      <button onClick={parar} disabled={!conectado}>Parar</button>\r\n      <button onClick={desconectar} disabled={!conectado}>Desconectar</button>\r\n      <p>Tags lidas: {tags.size}</p>\r\n      <ul>\r\n        {[...tags].map((epc) => <li key={epc}>{epc}</li>)}\r\n      </ul>\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n---\r\n\r\n## API — `ICardReader`\r\n\r\n### Conexão\r\n\r\n| Método | Descrição |\r\n|--------|-----------|\r\n| `connect(namePrefix?)` | Abre o seletor BLE e conecta. **Chamar em clique.** Retorna o nome do device. |\r\n| `connectToDevice(device)` | Conecta a um `BluetoothDevice` já obtido (reconexão). |\r\n| `disconnect()` | Encerra a conexão BLE. |\r\n| `isConnected` | `boolean` — se há conexão ativa. |\r\n| `onDisconnected(cb)` | Registra callback de queda da conexão GATT. |\r\n\r\n### Inventário (scan)\r\n\r\n| Método | Descrição |\r\n|--------|-----------|\r\n| `scan(callback)` | Inicia inventário contínuo. `callback(epcs: string[])` é chamado a cada ciclo com os EPCs hex lidos. |\r\n| `stopScan()` | Para o inventário. |\r\n| `isScanning` | `boolean` — se há scan ativo. |\r\n\r\n### Configuração do reader\r\n\r\n| Método | Descrição |\r\n|--------|-----------|\r\n| `getReaderInfo()` | Retorna `{ status, version, power, frequency }`. |\r\n| `setPower(0..30)` | Define a potência. Retorna `0` em sucesso. |\r\n| `setInventoryScanTime(3..255)` | Tempo de scan (cada unidade = 100ms). |\r\n| `setRegion(max, min)` | Frequência da região (Brasil: `15, 0`). |\r\n\r\n### Memória da tag (EPC Gen2)\r\n\r\n| Método | Descrição |\r\n|--------|-----------|\r\n| `readDataG2(epc, mem, wordAddr, num, psd?)` | Lê words da tag. Retorna `Uint8Array` ou `null`. |\r\n| `writeDataG2(epc, mem, wordAddr, data, psd?)` | Escreve words na tag. Retorna `0` em sucesso. |\r\n\r\n---\r\n\r\n## Exportações avançadas\r\n\r\nAlém da `ICardReader`, o pacote exporta utilitários de protocolo para uso em testes ou integrações de baixo nível:\r\n\r\n```ts\r\nimport {\r\n  // Transporte BLE\r\n  BleTransport,\r\n  UUID_CHAFON_RFID_SERVICE,\r\n  UUID_CHAFON_RFID_CHARACTERISTIC,\r\n\r\n  // Códigos de comando\r\n  EpcC1G2Command,\r\n  ReaderDefinedCommand,\r\n  CommandResultStatus,\r\n\r\n  // Parsing\r\n  parseResponseBuffer,\r\n  getInventoryDataBuffer,\r\n  parseInventoryResult,\r\n  extractEpcs,\r\n\r\n  // Construtores de frames\r\n  createInventoryG2StartMessage,\r\n  createReadDataG2Message,\r\n  createWriteG2Message,\r\n  createSetPowerMessage,\r\n  createSetInventoryScanTimeMessage,\r\n  createSetRegionMessage,\r\n  createGetReaderInfoMessage,\r\n\r\n  // Utilitários de bytes\r\n  bytesToHex,\r\n  hexToBytes,\r\n  execCRC,\r\n  checkCRC,\r\n} from '@4demar/icard-electron-sdk';\r\n```\r\n\r\n---\r\n\r\n## Regras de uso\r\n\r\n- **Um scan por vez.** Pare o scan (`stopScan()`) antes de enviar comandos de configuração — o\r\n  reader não processa ambos em paralelo. A SDK lança erro se tentar.\r\n- **Gesto do usuário obrigatório.** `connect()` depende de `requestDevice`, que só funciona a partir\r\n  de um clique. Não é possível conectar automaticamente no boot.\r\n- **Reconexão limitada.** Depende do Chromium/Electron reter permissão (`getDevices()` quando\r\n  disponível). Use `connectToDevice(device)` se tiver a referência do device.\r\n\r\n---\r\n\r\n## Publicação (mantenedores)\r\n\r\n```bash\r\ncd icard-electron-sdk\r\n\r\n# Autenticação (uma vez):\r\nnpm login --scope=@4demar --registry=https://npm.pkg.github.com\r\n\r\n# Publicar (roda build automaticamente via prepublishOnly):\r\nnpm publish\r\n```\r\n\r\nPara atualizar a versão:\r\n\r\n```bash\r\nnpm version patch   # ou minor / major\r\nnpm publish\r\n```\r\n\r\n---\r\n","readmeFilename":"README.md"}