capacitor-rfid-plugin-ox 0.4.0 → 0.5.0
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/README.md +171 -0
- package/dist/docs.json +226 -1
- package/dist/esm/definitions.d.ts +115 -1
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/electron-bridge.d.ts +30 -0
- package/dist/esm/electron-bridge.js +55 -0
- package/dist/esm/electron-bridge.js.map +1 -0
- package/dist/esm/index.js +4 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +15 -1
- package/dist/esm/web.js +18 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +76 -3
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +76 -3
- package/dist/plugin.js.map +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -14,6 +14,9 @@ npx cap sync
|
|
|
14
14
|
<docgen-index>
|
|
15
15
|
|
|
16
16
|
* [`getCapabilities()`](#getcapabilities)
|
|
17
|
+
* [`getConnectionState()`](#getconnectionstate)
|
|
18
|
+
* [`listReaderPorts()`](#listreaderports)
|
|
19
|
+
* [`selectReaderPort(...)`](#selectreaderport)
|
|
17
20
|
* [`isConnected()`](#isconnected)
|
|
18
21
|
* [`startScan()`](#startscan)
|
|
19
22
|
* [`stopScan()`](#stopscan)
|
|
@@ -31,7 +34,10 @@ npx cap sync
|
|
|
31
34
|
* [`writeEpcString(...)`](#writeepcstring)
|
|
32
35
|
* [`startSearch(...)`](#startsearch)
|
|
33
36
|
* [`stopSearch()`](#stopsearch)
|
|
37
|
+
* [`addListener('onConnectionState', ...)`](#addlisteneronconnectionstate-)
|
|
38
|
+
* [`addListener(string, ...)`](#addlistenerstring-)
|
|
34
39
|
* [Interfaces](#interfaces)
|
|
40
|
+
* [Type Aliases](#type-aliases)
|
|
35
41
|
|
|
36
42
|
</docgen-index>
|
|
37
43
|
|
|
@@ -54,6 +60,71 @@ failure: the caller treats a rejection as a handheld Mobile Reader.
|
|
|
54
60
|
--------------------
|
|
55
61
|
|
|
56
62
|
|
|
63
|
+
### getConnectionState()
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
getConnectionState() => Promise<ReaderConnectionState>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Connection state for the first render. The stream of later changes comes
|
|
70
|
+
from the `onConnectionState` listener — "not responding" is only found out
|
|
71
|
+
after a timeout, so it cannot be a return value.
|
|
72
|
+
|
|
73
|
+
A reader is an exclusive resource, so its state is only knowable while it
|
|
74
|
+
is held: an implementation that is not connected may start an attempt here
|
|
75
|
+
and answer `connecting`, with the outcome arriving on the listener.
|
|
76
|
+
|
|
77
|
+
Implementations that predate this method reject. The caller then hides the
|
|
78
|
+
indicator instead of guessing.
|
|
79
|
+
|
|
80
|
+
**Returns:** <code>Promise<<a href="#readerconnectionstate">ReaderConnectionState</a>></code>
|
|
81
|
+
|
|
82
|
+
--------------------
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
### listReaderPorts()
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
listReaderPorts() => Promise<{ ports: ReaderPort[]; }>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The readers plugged in right now, newest listing every call — a port that
|
|
92
|
+
was there a minute ago may be gone.
|
|
93
|
+
|
|
94
|
+
Only readers, not every serial port: what the caller does with this list
|
|
95
|
+
is offer it as a choice, and a Bluetooth port is not a choice.
|
|
96
|
+
|
|
97
|
+
Implementations that predate this method reject. The caller then keeps
|
|
98
|
+
whatever the driver picks on its own.
|
|
99
|
+
|
|
100
|
+
**Returns:** <code>Promise<{ ports: ReaderPort[]; }></code>
|
|
101
|
+
|
|
102
|
+
--------------------
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
### selectReaderPort(...)
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
selectReaderPort(options: { path: string; }) => Promise<void>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Use this reader from now on. Reconnects when another port is open.
|
|
112
|
+
|
|
113
|
+
The choice itself is not stored here: the driver is restarted with the
|
|
114
|
+
app, and where a choice belongs is the caller's question. The caller
|
|
115
|
+
remembers the path and says it again on the next start.
|
|
116
|
+
|
|
117
|
+
Rejects when the path is not in the current `listReaderPorts()` — a
|
|
118
|
+
remembered reader that was unplugged has to be chosen again, not opened
|
|
119
|
+
blindly.
|
|
120
|
+
|
|
121
|
+
| Param | Type |
|
|
122
|
+
| ------------- | ------------------------------ |
|
|
123
|
+
| **`options`** | <code>{ path: string; }</code> |
|
|
124
|
+
|
|
125
|
+
--------------------
|
|
126
|
+
|
|
127
|
+
|
|
57
128
|
### isConnected()
|
|
58
129
|
|
|
59
130
|
```typescript
|
|
@@ -255,6 +326,40 @@ stopSearch() => Promise<void>
|
|
|
255
326
|
--------------------
|
|
256
327
|
|
|
257
328
|
|
|
329
|
+
### addListener('onConnectionState', ...)
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
addListener(eventName: 'onConnectionState', listener: (state: ReaderConnectionState) => void) => Promise<PluginListenerHandle>
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Every connection state change. Fires only on a change, not on a poll.
|
|
336
|
+
|
|
337
|
+
| Param | Type |
|
|
338
|
+
| --------------- | ------------------------------------------------------------------------------------------- |
|
|
339
|
+
| **`eventName`** | <code>'onConnectionState'</code> |
|
|
340
|
+
| **`listener`** | <code>(state: <a href="#readerconnectionstate">ReaderConnectionState</a>) => void</code> |
|
|
341
|
+
|
|
342
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>
|
|
343
|
+
|
|
344
|
+
--------------------
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
### addListener(string, ...)
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
addListener(eventName: string, listenerFunc: (...args: any[]) => any) => Promise<PluginListenerHandle>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
| Param | Type |
|
|
354
|
+
| ------------------ | --------------------------------------- |
|
|
355
|
+
| **`eventName`** | <code>string</code> |
|
|
356
|
+
| **`listenerFunc`** | <code>(...args: any[]) => any</code> |
|
|
357
|
+
|
|
358
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>
|
|
359
|
+
|
|
360
|
+
--------------------
|
|
361
|
+
|
|
362
|
+
|
|
258
363
|
### Interfaces
|
|
259
364
|
|
|
260
365
|
|
|
@@ -271,4 +376,70 @@ that cannot.
|
|
|
271
376
|
| **`isHandheld`** | <code>boolean</code> | Reader is a handheld terminal rather than a desk device. |
|
|
272
377
|
| **`power`** | <code>{ min: number; max: number; default: number; }</code> | Output power range in dBm. The power slider renders this range. |
|
|
273
378
|
|
|
379
|
+
|
|
380
|
+
#### ReaderConnectionState
|
|
381
|
+
|
|
382
|
+
| Prop | Type | Description |
|
|
383
|
+
| ------------ | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
384
|
+
| **`status`** | <code><a href="#readerconnectionstatus">ReaderConnectionStatus</a></code> | |
|
|
385
|
+
| **`reason`** | <code><a href="#readerconnectionreason">ReaderConnectionReason</a></code> | |
|
|
386
|
+
| **`detail`** | <code>string</code> | Driver text: the port list, the command code, the OS error. This is the one field allowed to talk about the wiring, because nothing branches on it — it is shown as-is for support, not translated. |
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
#### ReaderPort
|
|
390
|
+
|
|
391
|
+
One reader the driver could talk to.
|
|
392
|
+
|
|
393
|
+
`path` is the identity — `COM3` on Windows, `/dev/cu.usbserial-110`
|
|
394
|
+
elsewhere. Two identical CH340 adapters carry no serial number of their own,
|
|
395
|
+
so the path is all that separates them.
|
|
396
|
+
|
|
397
|
+
The caller treats it as **opaque**: it compares, stores and hands it back,
|
|
398
|
+
and never reads meaning out of it. A driver for a device that is not a
|
|
399
|
+
serial port puts its own identity here.
|
|
400
|
+
|
|
401
|
+
| Prop | Type | Description |
|
|
402
|
+
| --------------- | ------------------- | ------------------------------------------------------------------------ |
|
|
403
|
+
| **`path`** | <code>string</code> | |
|
|
404
|
+
| **`label`** | <code>string</code> | What the OS calls the device. For the operator to read, not to match on. |
|
|
405
|
+
| **`vendorId`** | <code>string</code> | |
|
|
406
|
+
| **`productId`** | <code>string</code> | |
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
#### PluginListenerHandle
|
|
410
|
+
|
|
411
|
+
| Prop | Type |
|
|
412
|
+
| ------------ | ----------------------------------------- |
|
|
413
|
+
| **`remove`** | <code>() => Promise<void></code> |
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
### Type Aliases
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
#### ReaderConnectionStatus
|
|
420
|
+
|
|
421
|
+
The four states an operator can act on.
|
|
422
|
+
|
|
423
|
+
`isConnected()` is too coarse for this: a reader that is plugged in but
|
|
424
|
+
silent answers `false` the same way a missing one does, and the operator
|
|
425
|
+
needs a different move in each case. `isConnected()` stays as it is.
|
|
426
|
+
|
|
427
|
+
<code>'connecting' | 'connected' | 'not-found' | 'not-responding'</code>
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
#### ReaderConnectionReason
|
|
431
|
+
|
|
432
|
+
Why the reader is unusable. The status alone does not say what to do next:
|
|
433
|
+
a busy reader needs another program closed, a missing one needs the
|
|
434
|
+
connection checked. The UI picks its message from the reason when there is
|
|
435
|
+
one.
|
|
436
|
+
|
|
437
|
+
These name what happened to the *reader*, never how it is wired. A driver
|
|
438
|
+
for a device with no serial port has to be able to answer in this
|
|
439
|
+
vocabulary too, and the operator has to be told the truth either way —
|
|
440
|
+
so nothing here says "COM port" or "USB". The device-specific sentence
|
|
441
|
+
belongs in `detail`.
|
|
442
|
+
|
|
443
|
+
<code>'busy' | 'not-detected' | 'disconnected' | 'no-answer' | 'not-chosen'</code>
|
|
444
|
+
|
|
274
445
|
</docgen-api>
|
package/dist/docs.json
CHANGED
|
@@ -17,6 +17,46 @@
|
|
|
17
17
|
],
|
|
18
18
|
"slug": "getcapabilities"
|
|
19
19
|
},
|
|
20
|
+
{
|
|
21
|
+
"name": "getConnectionState",
|
|
22
|
+
"signature": "() => Promise<ReaderConnectionState>",
|
|
23
|
+
"parameters": [],
|
|
24
|
+
"returns": "Promise<ReaderConnectionState>",
|
|
25
|
+
"tags": [],
|
|
26
|
+
"docs": "Connection state for the first render. The stream of later changes comes\nfrom the `onConnectionState` listener — \"not responding\" is only found out\nafter a timeout, so it cannot be a return value.\n\nA reader is an exclusive resource, so its state is only knowable while it\nis held: an implementation that is not connected may start an attempt here\nand answer `connecting`, with the outcome arriving on the listener.\n\nImplementations that predate this method reject. The caller then hides the\nindicator instead of guessing.",
|
|
27
|
+
"complexTypes": [
|
|
28
|
+
"ReaderConnectionState"
|
|
29
|
+
],
|
|
30
|
+
"slug": "getconnectionstate"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "listReaderPorts",
|
|
34
|
+
"signature": "() => Promise<{ ports: ReaderPort[]; }>",
|
|
35
|
+
"parameters": [],
|
|
36
|
+
"returns": "Promise<{ ports: ReaderPort[]; }>",
|
|
37
|
+
"tags": [],
|
|
38
|
+
"docs": "The readers plugged in right now, newest listing every call — a port that\nwas there a minute ago may be gone.\n\nOnly readers, not every serial port: what the caller does with this list\nis offer it as a choice, and a Bluetooth port is not a choice.\n\nImplementations that predate this method reject. The caller then keeps\nwhatever the driver picks on its own.",
|
|
39
|
+
"complexTypes": [
|
|
40
|
+
"ReaderPort"
|
|
41
|
+
],
|
|
42
|
+
"slug": "listreaderports"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "selectReaderPort",
|
|
46
|
+
"signature": "(options: { path: string; }) => Promise<void>",
|
|
47
|
+
"parameters": [
|
|
48
|
+
{
|
|
49
|
+
"name": "options",
|
|
50
|
+
"docs": "",
|
|
51
|
+
"type": "{ path: string; }"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"returns": "Promise<void>",
|
|
55
|
+
"tags": [],
|
|
56
|
+
"docs": "Use this reader from now on. Reconnects when another port is open.\n\nThe choice itself is not stored here: the driver is restarted with the\napp, and where a choice belongs is the caller's question. The caller\nremembers the path and says it again on the next start.\n\nRejects when the path is not in the current `listReaderPorts()` — a\nremembered reader that was unplugged has to be chosen again, not opened\nblindly.",
|
|
57
|
+
"complexTypes": [],
|
|
58
|
+
"slug": "selectreaderport"
|
|
59
|
+
},
|
|
20
60
|
{
|
|
21
61
|
"name": "isConnected",
|
|
22
62
|
"signature": "() => Promise<{ connected: boolean; }>",
|
|
@@ -222,6 +262,53 @@
|
|
|
222
262
|
"docs": "",
|
|
223
263
|
"complexTypes": [],
|
|
224
264
|
"slug": "stopsearch"
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"name": "addListener",
|
|
268
|
+
"signature": "(eventName: 'onConnectionState', listener: (state: ReaderConnectionState) => void) => Promise<PluginListenerHandle>",
|
|
269
|
+
"parameters": [
|
|
270
|
+
{
|
|
271
|
+
"name": "eventName",
|
|
272
|
+
"docs": "",
|
|
273
|
+
"type": "'onConnectionState'"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"name": "listener",
|
|
277
|
+
"docs": "",
|
|
278
|
+
"type": "(state: ReaderConnectionState) => void"
|
|
279
|
+
}
|
|
280
|
+
],
|
|
281
|
+
"returns": "Promise<PluginListenerHandle>",
|
|
282
|
+
"tags": [],
|
|
283
|
+
"docs": "Every connection state change. Fires only on a change, not on a poll.",
|
|
284
|
+
"complexTypes": [
|
|
285
|
+
"PluginListenerHandle",
|
|
286
|
+
"ReaderConnectionState"
|
|
287
|
+
],
|
|
288
|
+
"slug": "addlisteneronconnectionstate-"
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"name": "addListener",
|
|
292
|
+
"signature": "(eventName: string, listenerFunc: (...args: any[]) => any) => Promise<PluginListenerHandle>",
|
|
293
|
+
"parameters": [
|
|
294
|
+
{
|
|
295
|
+
"name": "eventName",
|
|
296
|
+
"docs": "",
|
|
297
|
+
"type": "string"
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"name": "listenerFunc",
|
|
301
|
+
"docs": "",
|
|
302
|
+
"type": "(...args: any[]) => any"
|
|
303
|
+
}
|
|
304
|
+
],
|
|
305
|
+
"returns": "Promise<PluginListenerHandle>",
|
|
306
|
+
"tags": [],
|
|
307
|
+
"docs": "",
|
|
308
|
+
"complexTypes": [
|
|
309
|
+
"PluginListenerHandle"
|
|
310
|
+
],
|
|
311
|
+
"slug": "addlistenerstring-"
|
|
225
312
|
}
|
|
226
313
|
],
|
|
227
314
|
"properties": []
|
|
@@ -263,9 +350,147 @@
|
|
|
263
350
|
"type": "{ min: number; max: number; default: number; }"
|
|
264
351
|
}
|
|
265
352
|
]
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
"name": "ReaderConnectionState",
|
|
356
|
+
"slug": "readerconnectionstate",
|
|
357
|
+
"docs": "",
|
|
358
|
+
"tags": [],
|
|
359
|
+
"methods": [],
|
|
360
|
+
"properties": [
|
|
361
|
+
{
|
|
362
|
+
"name": "status",
|
|
363
|
+
"tags": [],
|
|
364
|
+
"docs": "",
|
|
365
|
+
"complexTypes": [
|
|
366
|
+
"ReaderConnectionStatus"
|
|
367
|
+
],
|
|
368
|
+
"type": "ReaderConnectionStatus"
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
"name": "reason",
|
|
372
|
+
"tags": [],
|
|
373
|
+
"docs": "",
|
|
374
|
+
"complexTypes": [
|
|
375
|
+
"ReaderConnectionReason"
|
|
376
|
+
],
|
|
377
|
+
"type": "ReaderConnectionReason"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"name": "detail",
|
|
381
|
+
"tags": [],
|
|
382
|
+
"docs": "Driver text: the port list, the command code, the OS error. This is the\none field allowed to talk about the wiring, because nothing branches on\nit — it is shown as-is for support, not translated.",
|
|
383
|
+
"complexTypes": [],
|
|
384
|
+
"type": "string | undefined"
|
|
385
|
+
}
|
|
386
|
+
]
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"name": "ReaderPort",
|
|
390
|
+
"slug": "readerport",
|
|
391
|
+
"docs": "One reader the driver could talk to.\n\n`path` is the identity — `COM3` on Windows, `/dev/cu.usbserial-110`\nelsewhere. Two identical CH340 adapters carry no serial number of their own,\nso the path is all that separates them.\n\nThe caller treats it as **opaque**: it compares, stores and hands it back,\nand never reads meaning out of it. A driver for a device that is not a\nserial port puts its own identity here.",
|
|
392
|
+
"tags": [],
|
|
393
|
+
"methods": [],
|
|
394
|
+
"properties": [
|
|
395
|
+
{
|
|
396
|
+
"name": "path",
|
|
397
|
+
"tags": [],
|
|
398
|
+
"docs": "",
|
|
399
|
+
"complexTypes": [],
|
|
400
|
+
"type": "string"
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
"name": "label",
|
|
404
|
+
"tags": [],
|
|
405
|
+
"docs": "What the OS calls the device. For the operator to read, not to match on.",
|
|
406
|
+
"complexTypes": [],
|
|
407
|
+
"type": "string | undefined"
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
"name": "vendorId",
|
|
411
|
+
"tags": [],
|
|
412
|
+
"docs": "",
|
|
413
|
+
"complexTypes": [],
|
|
414
|
+
"type": "string | undefined"
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"name": "productId",
|
|
418
|
+
"tags": [],
|
|
419
|
+
"docs": "",
|
|
420
|
+
"complexTypes": [],
|
|
421
|
+
"type": "string | undefined"
|
|
422
|
+
}
|
|
423
|
+
]
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
"name": "PluginListenerHandle",
|
|
427
|
+
"slug": "pluginlistenerhandle",
|
|
428
|
+
"docs": "",
|
|
429
|
+
"tags": [],
|
|
430
|
+
"methods": [],
|
|
431
|
+
"properties": [
|
|
432
|
+
{
|
|
433
|
+
"name": "remove",
|
|
434
|
+
"tags": [],
|
|
435
|
+
"docs": "",
|
|
436
|
+
"complexTypes": [],
|
|
437
|
+
"type": "() => Promise<void>"
|
|
438
|
+
}
|
|
439
|
+
]
|
|
266
440
|
}
|
|
267
441
|
],
|
|
268
442
|
"enums": [],
|
|
269
|
-
"typeAliases": [
|
|
443
|
+
"typeAliases": [
|
|
444
|
+
{
|
|
445
|
+
"name": "ReaderConnectionStatus",
|
|
446
|
+
"slug": "readerconnectionstatus",
|
|
447
|
+
"docs": "The four states an operator can act on.\n\n`isConnected()` is too coarse for this: a reader that is plugged in but\nsilent answers `false` the same way a missing one does, and the operator\nneeds a different move in each case. `isConnected()` stays as it is.",
|
|
448
|
+
"types": [
|
|
449
|
+
{
|
|
450
|
+
"text": "'connecting'",
|
|
451
|
+
"complexTypes": []
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
"text": "'connected'",
|
|
455
|
+
"complexTypes": []
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
"text": "'not-found'",
|
|
459
|
+
"complexTypes": []
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
"text": "'not-responding'",
|
|
463
|
+
"complexTypes": []
|
|
464
|
+
}
|
|
465
|
+
]
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
"name": "ReaderConnectionReason",
|
|
469
|
+
"slug": "readerconnectionreason",
|
|
470
|
+
"docs": "Why the reader is unusable. The status alone does not say what to do next:\na busy reader needs another program closed, a missing one needs the\nconnection checked. The UI picks its message from the reason when there is\none.\n\nThese name what happened to the *reader*, never how it is wired. A driver\nfor a device with no serial port has to be able to answer in this\nvocabulary too, and the operator has to be told the truth either way —\nso nothing here says \"COM port\" or \"USB\". The device-specific sentence\nbelongs in `detail`.",
|
|
471
|
+
"types": [
|
|
472
|
+
{
|
|
473
|
+
"text": "'busy'",
|
|
474
|
+
"complexTypes": []
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
"text": "'not-detected'",
|
|
478
|
+
"complexTypes": []
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
"text": "'disconnected'",
|
|
482
|
+
"complexTypes": []
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
"text": "'no-answer'",
|
|
486
|
+
"complexTypes": []
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
"text": "'not-chosen'",
|
|
490
|
+
"complexTypes": []
|
|
491
|
+
}
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
],
|
|
270
495
|
"pluginConfigs": []
|
|
271
496
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Plugin } from '@capacitor/core';
|
|
1
|
+
import type { Plugin, PluginListenerHandle } from '@capacitor/core';
|
|
2
2
|
/**
|
|
3
3
|
* What the connected Reader can do. Mode gating comes from here, not from the
|
|
4
4
|
* reader type — a desktop reader that can write must not be gated like one
|
|
@@ -18,6 +18,77 @@ export interface ReaderCapabilities {
|
|
|
18
18
|
default: number;
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* The four states an operator can act on.
|
|
23
|
+
*
|
|
24
|
+
* `isConnected()` is too coarse for this: a reader that is plugged in but
|
|
25
|
+
* silent answers `false` the same way a missing one does, and the operator
|
|
26
|
+
* needs a different move in each case. `isConnected()` stays as it is.
|
|
27
|
+
*/
|
|
28
|
+
export declare type ReaderConnectionStatus =
|
|
29
|
+
/** An attempt is running. */
|
|
30
|
+
'connecting'
|
|
31
|
+
/** The reader is open and answering. */
|
|
32
|
+
| 'connected'
|
|
33
|
+
/** No reader to talk to — nothing found, or found but not openable. */
|
|
34
|
+
| 'not-found'
|
|
35
|
+
/** The port opened but the reader did not answer a command. */
|
|
36
|
+
| 'not-responding';
|
|
37
|
+
/**
|
|
38
|
+
* Why the reader is unusable. The status alone does not say what to do next:
|
|
39
|
+
* a busy reader needs another program closed, a missing one needs the
|
|
40
|
+
* connection checked. The UI picks its message from the reason when there is
|
|
41
|
+
* one.
|
|
42
|
+
*
|
|
43
|
+
* These name what happened to the *reader*, never how it is wired. A driver
|
|
44
|
+
* for a device with no serial port has to be able to answer in this
|
|
45
|
+
* vocabulary too, and the operator has to be told the truth either way —
|
|
46
|
+
* so nothing here says "COM port" or "USB". The device-specific sentence
|
|
47
|
+
* belongs in `detail`.
|
|
48
|
+
*/
|
|
49
|
+
export declare type ReaderConnectionReason =
|
|
50
|
+
/** Another program holds the reader. Only one may have it at a time. */
|
|
51
|
+
'busy'
|
|
52
|
+
/** No reader in sight — nothing connected, or nothing that is a reader. */
|
|
53
|
+
| 'not-detected'
|
|
54
|
+
/** The reader was there and then went away. */
|
|
55
|
+
| 'disconnected'
|
|
56
|
+
/** The reader is reachable but did not answer. */
|
|
57
|
+
| 'no-answer'
|
|
58
|
+
/**
|
|
59
|
+
* Several readers are connected and none was picked. Guessing here would
|
|
60
|
+
* attach tags read by the wrong device, so nothing is opened until
|
|
61
|
+
* `selectReaderPort` says which one.
|
|
62
|
+
*/
|
|
63
|
+
| 'not-chosen';
|
|
64
|
+
export interface ReaderConnectionState {
|
|
65
|
+
status: ReaderConnectionStatus;
|
|
66
|
+
reason?: ReaderConnectionReason;
|
|
67
|
+
/**
|
|
68
|
+
* Driver text: the port list, the command code, the OS error. This is the
|
|
69
|
+
* one field allowed to talk about the wiring, because nothing branches on
|
|
70
|
+
* it — it is shown as-is for support, not translated.
|
|
71
|
+
*/
|
|
72
|
+
detail?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* One reader the driver could talk to.
|
|
76
|
+
*
|
|
77
|
+
* `path` is the identity — `COM3` on Windows, `/dev/cu.usbserial-110`
|
|
78
|
+
* elsewhere. Two identical CH340 adapters carry no serial number of their own,
|
|
79
|
+
* so the path is all that separates them.
|
|
80
|
+
*
|
|
81
|
+
* The caller treats it as **opaque**: it compares, stores and hands it back,
|
|
82
|
+
* and never reads meaning out of it. A driver for a device that is not a
|
|
83
|
+
* serial port puts its own identity here.
|
|
84
|
+
*/
|
|
85
|
+
export interface ReaderPort {
|
|
86
|
+
path: string;
|
|
87
|
+
/** What the OS calls the device. For the operator to read, not to match on. */
|
|
88
|
+
label?: string;
|
|
89
|
+
vendorId?: string;
|
|
90
|
+
productId?: string;
|
|
91
|
+
}
|
|
21
92
|
export interface RFIDPlugin extends Plugin {
|
|
22
93
|
/**
|
|
23
94
|
* Capabilities of the connected Reader.
|
|
@@ -26,6 +97,46 @@ export interface RFIDPlugin extends Plugin {
|
|
|
26
97
|
* failure: the caller treats a rejection as a handheld Mobile Reader.
|
|
27
98
|
*/
|
|
28
99
|
getCapabilities(): Promise<ReaderCapabilities>;
|
|
100
|
+
/**
|
|
101
|
+
* Connection state for the first render. The stream of later changes comes
|
|
102
|
+
* from the `onConnectionState` listener — "not responding" is only found out
|
|
103
|
+
* after a timeout, so it cannot be a return value.
|
|
104
|
+
*
|
|
105
|
+
* A reader is an exclusive resource, so its state is only knowable while it
|
|
106
|
+
* is held: an implementation that is not connected may start an attempt here
|
|
107
|
+
* and answer `connecting`, with the outcome arriving on the listener.
|
|
108
|
+
*
|
|
109
|
+
* Implementations that predate this method reject. The caller then hides the
|
|
110
|
+
* indicator instead of guessing.
|
|
111
|
+
*/
|
|
112
|
+
getConnectionState(): Promise<ReaderConnectionState>;
|
|
113
|
+
/**
|
|
114
|
+
* The readers plugged in right now, newest listing every call — a port that
|
|
115
|
+
* was there a minute ago may be gone.
|
|
116
|
+
*
|
|
117
|
+
* Only readers, not every serial port: what the caller does with this list
|
|
118
|
+
* is offer it as a choice, and a Bluetooth port is not a choice.
|
|
119
|
+
*
|
|
120
|
+
* Implementations that predate this method reject. The caller then keeps
|
|
121
|
+
* whatever the driver picks on its own.
|
|
122
|
+
*/
|
|
123
|
+
listReaderPorts(): Promise<{
|
|
124
|
+
ports: ReaderPort[];
|
|
125
|
+
}>;
|
|
126
|
+
/**
|
|
127
|
+
* Use this reader from now on. Reconnects when another port is open.
|
|
128
|
+
*
|
|
129
|
+
* The choice itself is not stored here: the driver is restarted with the
|
|
130
|
+
* app, and where a choice belongs is the caller's question. The caller
|
|
131
|
+
* remembers the path and says it again on the next start.
|
|
132
|
+
*
|
|
133
|
+
* Rejects when the path is not in the current `listReaderPorts()` — a
|
|
134
|
+
* remembered reader that was unplugged has to be chosen again, not opened
|
|
135
|
+
* blindly.
|
|
136
|
+
*/
|
|
137
|
+
selectReaderPort(options: {
|
|
138
|
+
path: string;
|
|
139
|
+
}): Promise<void>;
|
|
29
140
|
isConnected(): Promise<{
|
|
30
141
|
connected: boolean;
|
|
31
142
|
}>;
|
|
@@ -80,4 +191,7 @@ export interface RFIDPlugin extends Plugin {
|
|
|
80
191
|
playSound: boolean;
|
|
81
192
|
}): Promise<void>;
|
|
82
193
|
stopSearch(): Promise<void>;
|
|
194
|
+
/** Every connection state change. Fires only on a change, not on a poll. */
|
|
195
|
+
addListener(eventName: 'onConnectionState', listener: (state: ReaderConnectionState) => void): Promise<PluginListenerHandle>;
|
|
196
|
+
addListener(eventName: string, listenerFunc: (...args: any[]) => any): Promise<PluginListenerHandle>;
|
|
83
197
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { Plugin } from '@capacitor/core';\n\n/**\n * What the connected Reader can do. Mode gating comes from here, not from the\n * reader type — a desktop reader that can write must not be gated like one\n * that cannot.\n */\nexport interface ReaderCapabilities {\n /** Reader can write an EPC to a tag (Generate & Set mode depends on it). */\n canWrite: boolean;\n /** Reader reports RSSI (Find mode depends on it). */\n hasRssi: boolean;\n /** Reader is a handheld terminal rather than a desk device. */\n isHandheld: boolean;\n /** Output power range in dBm. The power slider renders this range. */\n power: {\n min: number;\n max: number;\n default: number;\n };\n}\n\nexport interface RFIDPlugin extends Plugin {\n /**\n * Capabilities of the connected Reader.\n *\n * Implementations that predate this method reject. That is a signal, not a\n * failure: the caller treats a rejection as a handheld Mobile Reader.\n */\n getCapabilities(): Promise<ReaderCapabilities>;\n\n isConnected(): Promise<{ connected: boolean }>;\n\n startScan(): Promise<void>;\n stopScan(): Promise<void>;\n clearData(): Promise<void>;\n\n getScanData(): Promise<any>;\n getOutputPower(): Promise<{ value: number }>;\n setOutputPower(options: { power: number }): Promise<{ value: number }>;\n\n getRange(): Promise<{ value: number }>;\n setRange(options: { range: number }): Promise<{ value: number }>;\n\n getQueryMode(): Promise<{ value: 0 | 1 | 2 | 3 }>;\n setQueryMode(options: {\n queryMode:\n | 0 // epc\n | 1 // epc+tid\n | 2 // epc+user\n | 3; // fasttid\n }): Promise<{ value: number }>;\n\n getReaderType(): Promise<{ value: number }>; // 80 - short, others - long distance mode\n getFirmwareVersion(): Promise<{ value: string }>;\n\n writeEpc(options: {\n epc: string;\n password?: string;\n }): Promise<{ value: number }>;\n writeEpcString(options: {\n epc: string;\n password?: string;\n }): Promise<{ value: number }>;\n\n startSearch(options: { searchableTags: string[], playSound: boolean }): Promise<void>;\n stopSearch(): Promise<void>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { Plugin, PluginListenerHandle } from '@capacitor/core';\n\n/**\n * What the connected Reader can do. Mode gating comes from here, not from the\n * reader type — a desktop reader that can write must not be gated like one\n * that cannot.\n */\nexport interface ReaderCapabilities {\n /** Reader can write an EPC to a tag (Generate & Set mode depends on it). */\n canWrite: boolean;\n /** Reader reports RSSI (Find mode depends on it). */\n hasRssi: boolean;\n /** Reader is a handheld terminal rather than a desk device. */\n isHandheld: boolean;\n /** Output power range in dBm. The power slider renders this range. */\n power: {\n min: number;\n max: number;\n default: number;\n };\n}\n\n/**\n * The four states an operator can act on.\n *\n * `isConnected()` is too coarse for this: a reader that is plugged in but\n * silent answers `false` the same way a missing one does, and the operator\n * needs a different move in each case. `isConnected()` stays as it is.\n */\nexport type ReaderConnectionStatus =\n /** An attempt is running. */\n | 'connecting'\n /** The reader is open and answering. */\n | 'connected'\n /** No reader to talk to — nothing found, or found but not openable. */\n | 'not-found'\n /** The port opened but the reader did not answer a command. */\n | 'not-responding';\n\n/**\n * Why the reader is unusable. The status alone does not say what to do next:\n * a busy reader needs another program closed, a missing one needs the\n * connection checked. The UI picks its message from the reason when there is\n * one.\n *\n * These name what happened to the *reader*, never how it is wired. A driver\n * for a device with no serial port has to be able to answer in this\n * vocabulary too, and the operator has to be told the truth either way —\n * so nothing here says \"COM port\" or \"USB\". The device-specific sentence\n * belongs in `detail`.\n */\nexport type ReaderConnectionReason =\n /** Another program holds the reader. Only one may have it at a time. */\n | 'busy'\n /** No reader in sight — nothing connected, or nothing that is a reader. */\n | 'not-detected'\n /** The reader was there and then went away. */\n | 'disconnected'\n /** The reader is reachable but did not answer. */\n | 'no-answer'\n /**\n * Several readers are connected and none was picked. Guessing here would\n * attach tags read by the wrong device, so nothing is opened until\n * `selectReaderPort` says which one.\n */\n | 'not-chosen';\n\nexport interface ReaderConnectionState {\n status: ReaderConnectionStatus;\n reason?: ReaderConnectionReason;\n /**\n * Driver text: the port list, the command code, the OS error. This is the\n * one field allowed to talk about the wiring, because nothing branches on\n * it — it is shown as-is for support, not translated.\n */\n detail?: string;\n}\n\n/**\n * One reader the driver could talk to.\n *\n * `path` is the identity — `COM3` on Windows, `/dev/cu.usbserial-110`\n * elsewhere. Two identical CH340 adapters carry no serial number of their own,\n * so the path is all that separates them.\n *\n * The caller treats it as **opaque**: it compares, stores and hands it back,\n * and never reads meaning out of it. A driver for a device that is not a\n * serial port puts its own identity here.\n */\nexport interface ReaderPort {\n path: string;\n /** What the OS calls the device. For the operator to read, not to match on. */\n label?: string;\n vendorId?: string;\n productId?: string;\n}\n\nexport interface RFIDPlugin extends Plugin {\n /**\n * Capabilities of the connected Reader.\n *\n * Implementations that predate this method reject. That is a signal, not a\n * failure: the caller treats a rejection as a handheld Mobile Reader.\n */\n getCapabilities(): Promise<ReaderCapabilities>;\n\n /**\n * Connection state for the first render. The stream of later changes comes\n * from the `onConnectionState` listener — \"not responding\" is only found out\n * after a timeout, so it cannot be a return value.\n *\n * A reader is an exclusive resource, so its state is only knowable while it\n * is held: an implementation that is not connected may start an attempt here\n * and answer `connecting`, with the outcome arriving on the listener.\n *\n * Implementations that predate this method reject. The caller then hides the\n * indicator instead of guessing.\n */\n getConnectionState(): Promise<ReaderConnectionState>;\n\n /**\n * The readers plugged in right now, newest listing every call — a port that\n * was there a minute ago may be gone.\n *\n * Only readers, not every serial port: what the caller does with this list\n * is offer it as a choice, and a Bluetooth port is not a choice.\n *\n * Implementations that predate this method reject. The caller then keeps\n * whatever the driver picks on its own.\n */\n listReaderPorts(): Promise<{ ports: ReaderPort[] }>;\n\n /**\n * Use this reader from now on. Reconnects when another port is open.\n *\n * The choice itself is not stored here: the driver is restarted with the\n * app, and where a choice belongs is the caller's question. The caller\n * remembers the path and says it again on the next start.\n *\n * Rejects when the path is not in the current `listReaderPorts()` — a\n * remembered reader that was unplugged has to be chosen again, not opened\n * blindly.\n */\n selectReaderPort(options: { path: string }): Promise<void>;\n\n isConnected(): Promise<{ connected: boolean }>;\n\n startScan(): Promise<void>;\n stopScan(): Promise<void>;\n clearData(): Promise<void>;\n\n getScanData(): Promise<any>;\n getOutputPower(): Promise<{ value: number }>;\n setOutputPower(options: { power: number }): Promise<{ value: number }>;\n\n getRange(): Promise<{ value: number }>;\n setRange(options: { range: number }): Promise<{ value: number }>;\n\n getQueryMode(): Promise<{ value: 0 | 1 | 2 | 3 }>;\n setQueryMode(options: {\n queryMode:\n | 0 // epc\n | 1 // epc+tid\n | 2 // epc+user\n | 3; // fasttid\n }): Promise<{ value: number }>;\n\n getReaderType(): Promise<{ value: number }>; // 80 - short, others - long distance mode\n getFirmwareVersion(): Promise<{ value: string }>;\n\n writeEpc(options: {\n epc: string;\n password?: string;\n }): Promise<{ value: number }>;\n writeEpcString(options: {\n epc: string;\n password?: string;\n }): Promise<{ value: number }>;\n\n startSearch(options: { searchableTags: string[], playSound: boolean }): Promise<void>;\n stopSearch(): Promise<void>;\n\n /** Every connection state change. Fires only on a change, not on a poll. */\n addListener(\n eventName: 'onConnectionState',\n listener: (state: ReaderConnectionState) => void,\n ): Promise<PluginListenerHandle>;\n\n addListener(\n eventName: string,\n listenerFunc: (...args: any[]) => any,\n ): Promise<PluginListenerHandle>;\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { RFIDPlugin } from './definitions';
|
|
2
|
+
/**
|
|
3
|
+
* The bridge built by the `@capacitor-community/electron` preload
|
|
4
|
+
* (`electron-rt.ts`). Its `addListener` returns an id **string** and is
|
|
5
|
+
* synchronous — `removeListener` takes that same id.
|
|
6
|
+
*/
|
|
7
|
+
export interface ElectronBridge {
|
|
8
|
+
addListener(eventName: string, callback: (...args: any[]) => void): string;
|
|
9
|
+
removeListener(id: string): void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* On native platforms Capacitor wraps the `addListener` result into a
|
|
13
|
+
* `PluginListenerHandle` itself (`addListenerNative`), but only when
|
|
14
|
+
* `PluginHeaders` are present. Electron has none, so the bridge's raw id
|
|
15
|
+
* string reaches the UI as-is and `handle.remove()` is missing: the listener
|
|
16
|
+
* is never removed, and scanning does not start the second time the modal
|
|
17
|
+
* opens.
|
|
18
|
+
*
|
|
19
|
+
* Do not wrap it with a `Proxy`. Methods of an object exposed through
|
|
20
|
+
* `contextBridge` arrive as `writable: false, configurable: false`, and for
|
|
21
|
+
* such a property a `get` trap must return **that exact value** — even a
|
|
22
|
+
* bound copy is rejected. Otherwise the engine throws the error we saw on
|
|
23
|
+
* the device:
|
|
24
|
+
* TypeError: 'get' on proxy: property 'startScan' is a read-only and
|
|
25
|
+
* non-configurable data property on the proxy target but the proxy did
|
|
26
|
+
* not return its actual value
|
|
27
|
+
* So the bridge is used as the prototype instead: the other methods are
|
|
28
|
+
* found on it as usual, and only `addListener` is defined on top.
|
|
29
|
+
*/
|
|
30
|
+
export declare function withListenerHandles(bridge: ElectronBridge): RFIDPlugin;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const SCAN_EVENT = 'onScanEvent';
|
|
2
|
+
/**
|
|
3
|
+
* The Electron main process sends the tags it read in one message per 250 ms
|
|
4
|
+
* window instead of one per frame — a single tag is read about 44 times a
|
|
5
|
+
* second. The contract does not change: the array is unrolled here, so a
|
|
6
|
+
* listener still gets one tag per call.
|
|
7
|
+
*/
|
|
8
|
+
const SCAN_BATCH_EVENT = 'onScanEventBatch';
|
|
9
|
+
/**
|
|
10
|
+
* On native platforms Capacitor wraps the `addListener` result into a
|
|
11
|
+
* `PluginListenerHandle` itself (`addListenerNative`), but only when
|
|
12
|
+
* `PluginHeaders` are present. Electron has none, so the bridge's raw id
|
|
13
|
+
* string reaches the UI as-is and `handle.remove()` is missing: the listener
|
|
14
|
+
* is never removed, and scanning does not start the second time the modal
|
|
15
|
+
* opens.
|
|
16
|
+
*
|
|
17
|
+
* Do not wrap it with a `Proxy`. Methods of an object exposed through
|
|
18
|
+
* `contextBridge` arrive as `writable: false, configurable: false`, and for
|
|
19
|
+
* such a property a `get` trap must return **that exact value** — even a
|
|
20
|
+
* bound copy is rejected. Otherwise the engine throws the error we saw on
|
|
21
|
+
* the device:
|
|
22
|
+
* TypeError: 'get' on proxy: property 'startScan' is a read-only and
|
|
23
|
+
* non-configurable data property on the proxy target but the proxy did
|
|
24
|
+
* not return its actual value
|
|
25
|
+
* So the bridge is used as the prototype instead: the other methods are
|
|
26
|
+
* found on it as usual, and only `addListener` is defined on top.
|
|
27
|
+
*/
|
|
28
|
+
export function withListenerHandles(bridge) {
|
|
29
|
+
const plugin = Object.create(bridge);
|
|
30
|
+
// A plain `plugin.addListener = ...` does not work: the prototype property
|
|
31
|
+
// is `writable: false`, so [[Set]] blocks it.
|
|
32
|
+
Object.defineProperty(plugin, 'addListener', {
|
|
33
|
+
value: async (eventName, callback) => {
|
|
34
|
+
const ids = [bridge.addListener(eventName, callback)];
|
|
35
|
+
if (eventName === SCAN_EVENT) {
|
|
36
|
+
// A desktop app older than the batch sends one message per tag on
|
|
37
|
+
// `onScanEvent`, a newer one sends only batches. Both are listened
|
|
38
|
+
// for, because the bundle in the browser and the installed desktop
|
|
39
|
+
// app are updated separately; only one of them ever fires.
|
|
40
|
+
ids.push(bridge.addListener(SCAN_BATCH_EVENT, (batch) => {
|
|
41
|
+
for (const event of batch)
|
|
42
|
+
callback(event);
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
remove: async () => {
|
|
47
|
+
for (const id of ids)
|
|
48
|
+
bridge.removeListener(id);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
return plugin;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=electron-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"electron-bridge.js","sourceRoot":"","sources":["../../src/electron-bridge.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,GAAG,aAAa,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAsB;IACxD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAe,CAAC;IAEnD,2EAA2E;IAC3E,8CAA8C;IAC9C,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE;QAC3C,KAAK,EAAE,KAAK,EACV,SAAiB,EACjB,QAAkC,EACH,EAAE;YACjC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;YAEtD,IAAI,SAAS,KAAK,UAAU,EAAE;gBAC5B,kEAAkE;gBAClE,mEAAmE;gBACnE,mEAAmE;gBACnE,2DAA2D;gBAC3D,GAAG,CAAC,IAAI,CACN,MAAM,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC,KAAgB,EAAE,EAAE;oBACxD,KAAK,MAAM,KAAK,IAAI,KAAK;wBAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAC7C,CAAC,CAAC,CACH,CAAC;aACH;YAED,OAAO;gBACL,MAAM,EAAE,KAAK,IAAI,EAAE;oBACjB,KAAK,MAAM,EAAE,IAAI,GAAG;wBAAE,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;gBAClD,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\nimport type { RFIDPlugin } from './definitions';\n\n/**\n * The bridge built by the `@capacitor-community/electron` preload\n * (`electron-rt.ts`). Its `addListener` returns an id **string** and is\n * synchronous — `removeListener` takes that same id.\n */\nexport interface ElectronBridge {\n addListener(eventName: string, callback: (...args: any[]) => void): string;\n removeListener(id: string): void;\n}\n\nconst SCAN_EVENT = 'onScanEvent';\n\n/**\n * The Electron main process sends the tags it read in one message per 250 ms\n * window instead of one per frame — a single tag is read about 44 times a\n * second. The contract does not change: the array is unrolled here, so a\n * listener still gets one tag per call.\n */\nconst SCAN_BATCH_EVENT = 'onScanEventBatch';\n\n/**\n * On native platforms Capacitor wraps the `addListener` result into a\n * `PluginListenerHandle` itself (`addListenerNative`), but only when\n * `PluginHeaders` are present. Electron has none, so the bridge's raw id\n * string reaches the UI as-is and `handle.remove()` is missing: the listener\n * is never removed, and scanning does not start the second time the modal\n * opens.\n *\n * Do not wrap it with a `Proxy`. Methods of an object exposed through\n * `contextBridge` arrive as `writable: false, configurable: false`, and for\n * such a property a `get` trap must return **that exact value** — even a\n * bound copy is rejected. Otherwise the engine throws the error we saw on\n * the device:\n * TypeError: 'get' on proxy: property 'startScan' is a read-only and\n * non-configurable data property on the proxy target but the proxy did\n * not return its actual value\n * So the bridge is used as the prototype instead: the other methods are\n * found on it as usual, and only `addListener` is defined on top.\n */\nexport function withListenerHandles(bridge: ElectronBridge): RFIDPlugin {\n const plugin = Object.create(bridge) as RFIDPlugin;\n\n // A plain `plugin.addListener = ...` does not work: the prototype property\n // is `writable: false`, so [[Set]] blocks it.\n Object.defineProperty(plugin, 'addListener', {\n value: async (\n eventName: string,\n callback: (...args: any[]) => void,\n ): Promise<PluginListenerHandle> => {\n const ids = [bridge.addListener(eventName, callback)];\n\n if (eventName === SCAN_EVENT) {\n // A desktop app older than the batch sends one message per tag on\n // `onScanEvent`, a newer one sends only batches. Both are listened\n // for, because the bundle in the browser and the installed desktop\n // app are updated separately; only one of them ever fires.\n ids.push(\n bridge.addListener(SCAN_BATCH_EVENT, (batch: unknown[]) => {\n for (const event of batch) callback(event);\n }),\n );\n }\n\n return {\n remove: async () => {\n for (const id of ids) bridge.removeListener(id);\n },\n };\n },\n });\n\n return plugin;\n}\n"]}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { registerPlugin } from '@capacitor/core';
|
|
2
|
+
import { withListenerHandles } from './electron-bridge';
|
|
2
3
|
const RFID = registerPlugin('RFID', {
|
|
3
4
|
web: () => import('./web').then(m => new m.RFIDWeb()),
|
|
4
5
|
electron: () => {
|
|
5
6
|
var _a, _b;
|
|
6
|
-
const
|
|
7
|
-
if (!
|
|
7
|
+
const bridge = (_b = (_a = window.CapacitorCustomPlatform) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.RFID;
|
|
8
|
+
if (!bridge) {
|
|
8
9
|
throw new Error('RFID is not registered in the Electron runtime. Register the driver in electron-plugins.js.');
|
|
9
10
|
}
|
|
10
|
-
return
|
|
11
|
+
return withListenerHandles(bridge);
|
|
11
12
|
},
|
|
12
13
|
});
|
|
13
14
|
export * from './definitions';
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAMxD,MAAM,IAAI,GAAG,cAAc,CAAa,MAAM,EAAE;IAC9C,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IACrD,QAAQ,EAAE,GAAG,EAAE;;QACb,MAAM,MAAM,eAAI,MAAyB,CAAC,uBAAuB,0CAAE,OAAO,0CACtE,IAAI,CAAC;QAET,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;SACH;QAED,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;CACF,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { RFIDPlugin } from './definitions';\nimport type { ElectronBridge } from './electron-bridge';\nimport { withListenerHandles } from './electron-bridge';\n\ntype ElectronWindow = Window & {\n CapacitorCustomPlatform?: { plugins?: { RFID?: ElectronBridge } };\n};\n\nconst RFID = registerPlugin<RFIDPlugin>('RFID', {\n web: () => import('./web').then(m => new m.RFIDWeb()),\n electron: () => {\n const bridge = (window as ElectronWindow).CapacitorCustomPlatform?.plugins\n ?.RFID;\n\n if (!bridge) {\n throw new Error(\n 'RFID is not registered in the Electron runtime. Register the driver in electron-plugins.js.',\n );\n }\n\n return withListenerHandles(bridge);\n },\n});\n\nexport * from './definitions';\nexport { RFID };\n"]}
|
package/dist/esm/web.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WebPlugin } from '@capacitor/core';
|
|
2
2
|
import type { PluginListenerHandle } from '@capacitor/core';
|
|
3
|
-
import type { ReaderCapabilities, RFIDPlugin } from './definitions';
|
|
3
|
+
import type { ReaderCapabilities, ReaderConnectionState, ReaderPort, RFIDPlugin } from './definitions';
|
|
4
4
|
export declare class RFIDWeb extends WebPlugin implements RFIDPlugin {
|
|
5
5
|
/**
|
|
6
6
|
* The one method the browser can answer truthfully. Everything else rejects:
|
|
@@ -15,6 +15,20 @@ export declare class RFIDWeb extends WebPlugin implements RFIDPlugin {
|
|
|
15
15
|
*/
|
|
16
16
|
addListener(): Promise<PluginListenerHandle>;
|
|
17
17
|
getCapabilities(): Promise<ReaderCapabilities>;
|
|
18
|
+
/**
|
|
19
|
+
* Not `not-found`: that state tells the operator to check the cable, and
|
|
20
|
+
* there is no cable to check in a browser. The rejection carries the one
|
|
21
|
+
* useful sentence — open the desktop app or the handheld.
|
|
22
|
+
*/
|
|
23
|
+
getConnectionState(): Promise<ReaderConnectionState>;
|
|
24
|
+
/**
|
|
25
|
+
* Not an empty list: "no readers plugged in" would send the operator to look
|
|
26
|
+
* for a cable, and the browser has no serial ports to look at.
|
|
27
|
+
*/
|
|
28
|
+
listReaderPorts(): Promise<{
|
|
29
|
+
ports: ReaderPort[];
|
|
30
|
+
}>;
|
|
31
|
+
selectReaderPort(): Promise<void>;
|
|
18
32
|
startScan(): Promise<void>;
|
|
19
33
|
stopScan(): Promise<void>;
|
|
20
34
|
clearData(): Promise<void>;
|
package/dist/esm/web.js
CHANGED
|
@@ -18,6 +18,24 @@ export class RFIDWeb extends WebPlugin {
|
|
|
18
18
|
async getCapabilities() {
|
|
19
19
|
throw this.unimplemented(NO_READER_ON_WEB);
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Not `not-found`: that state tells the operator to check the cable, and
|
|
23
|
+
* there is no cable to check in a browser. The rejection carries the one
|
|
24
|
+
* useful sentence — open the desktop app or the handheld.
|
|
25
|
+
*/
|
|
26
|
+
async getConnectionState() {
|
|
27
|
+
throw this.unimplemented(NO_READER_ON_WEB);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Not an empty list: "no readers plugged in" would send the operator to look
|
|
31
|
+
* for a cable, and the browser has no serial ports to look at.
|
|
32
|
+
*/
|
|
33
|
+
async listReaderPorts() {
|
|
34
|
+
throw this.unimplemented(NO_READER_ON_WEB);
|
|
35
|
+
}
|
|
36
|
+
async selectReaderPort() {
|
|
37
|
+
throw this.unimplemented(NO_READER_ON_WEB);
|
|
38
|
+
}
|
|
21
39
|
async startScan() {
|
|
22
40
|
throw this.unimplemented(NO_READER_ON_WEB);
|
|
23
41
|
}
|
package/dist/esm/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C,MAAM,gBAAgB,GACpB,0FAA0F,CAAC;AAE7F,MAAM,OAAO,OAAQ,SAAQ,SAAS;IACpC;;;OAGG;IACH,KAAK,CAAC,WAAW;QACf,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW;QACf,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,eAAe;QACnB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,kBAAkB;QACtB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC7C,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\nimport type { PluginListenerHandle } from '@capacitor/core';\n\nimport type {\n ReaderCapabilities,\n ReaderConnectionState,\n ReaderPort,\n RFIDPlugin,\n} from './definitions';\n\nconst NO_READER_ON_WEB =\n 'No RFID Reader in the browser. Use the desktop app (ox-desktop) or the Android handheld.';\n\nexport class RFIDWeb extends WebPlugin implements RFIDPlugin {\n /**\n * The one method the browser can answer truthfully. Everything else rejects:\n * a silent `resolve` makes the UI report a success that never happened.\n */\n async isConnected(): Promise<{ connected: boolean }> {\n return { connected: false };\n }\n\n /**\n * Events never fire without a Reader, so registering a listener here would be\n * the same silent lie as a resolving `startScan()`.\n */\n async addListener(): Promise<PluginListenerHandle> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async getCapabilities(): Promise<ReaderCapabilities> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n /**\n * Not `not-found`: that state tells the operator to check the cable, and\n * there is no cable to check in a browser. The rejection carries the one\n * useful sentence — open the desktop app or the handheld.\n */\n async getConnectionState(): Promise<ReaderConnectionState> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n /**\n * Not an empty list: \"no readers plugged in\" would send the operator to look\n * for a cable, and the browser has no serial ports to look at.\n */\n async listReaderPorts(): Promise<{ ports: ReaderPort[] }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async selectReaderPort(): Promise<void> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async startScan(): Promise<void> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async stopScan(): Promise<void> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async clearData(): Promise<void> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async getScanData(): Promise<any> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async getOutputPower(): Promise<{ value: number }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async setOutputPower(): Promise<{ value: number }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async getRange(): Promise<{ value: number }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async setRange(): Promise<{ value: number }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async getQueryMode(): Promise<{ value: 0 | 1 | 2 | 3 }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async setQueryMode(): Promise<{ value: number }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async getReaderType(): Promise<{ value: number }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async getFirmwareVersion(): Promise<{ value: string }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async writeEpc(): Promise<{ value: number }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async writeEpcString(): Promise<{ value: number }> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async startSearch(): Promise<void> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n\n async stopSearch(): Promise<void> {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n}\n"]}
|
package/dist/plugin.cjs.js
CHANGED
|
@@ -4,15 +4,70 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var core = require('@capacitor/core');
|
|
6
6
|
|
|
7
|
+
const SCAN_EVENT = 'onScanEvent';
|
|
8
|
+
/**
|
|
9
|
+
* The Electron main process sends the tags it read in one message per 250 ms
|
|
10
|
+
* window instead of one per frame — a single tag is read about 44 times a
|
|
11
|
+
* second. The contract does not change: the array is unrolled here, so a
|
|
12
|
+
* listener still gets one tag per call.
|
|
13
|
+
*/
|
|
14
|
+
const SCAN_BATCH_EVENT = 'onScanEventBatch';
|
|
15
|
+
/**
|
|
16
|
+
* On native platforms Capacitor wraps the `addListener` result into a
|
|
17
|
+
* `PluginListenerHandle` itself (`addListenerNative`), but only when
|
|
18
|
+
* `PluginHeaders` are present. Electron has none, so the bridge's raw id
|
|
19
|
+
* string reaches the UI as-is and `handle.remove()` is missing: the listener
|
|
20
|
+
* is never removed, and scanning does not start the second time the modal
|
|
21
|
+
* opens.
|
|
22
|
+
*
|
|
23
|
+
* Do not wrap it with a `Proxy`. Methods of an object exposed through
|
|
24
|
+
* `contextBridge` arrive as `writable: false, configurable: false`, and for
|
|
25
|
+
* such a property a `get` trap must return **that exact value** — even a
|
|
26
|
+
* bound copy is rejected. Otherwise the engine throws the error we saw on
|
|
27
|
+
* the device:
|
|
28
|
+
* TypeError: 'get' on proxy: property 'startScan' is a read-only and
|
|
29
|
+
* non-configurable data property on the proxy target but the proxy did
|
|
30
|
+
* not return its actual value
|
|
31
|
+
* So the bridge is used as the prototype instead: the other methods are
|
|
32
|
+
* found on it as usual, and only `addListener` is defined on top.
|
|
33
|
+
*/
|
|
34
|
+
function withListenerHandles(bridge) {
|
|
35
|
+
const plugin = Object.create(bridge);
|
|
36
|
+
// A plain `plugin.addListener = ...` does not work: the prototype property
|
|
37
|
+
// is `writable: false`, so [[Set]] blocks it.
|
|
38
|
+
Object.defineProperty(plugin, 'addListener', {
|
|
39
|
+
value: async (eventName, callback) => {
|
|
40
|
+
const ids = [bridge.addListener(eventName, callback)];
|
|
41
|
+
if (eventName === SCAN_EVENT) {
|
|
42
|
+
// A desktop app older than the batch sends one message per tag on
|
|
43
|
+
// `onScanEvent`, a newer one sends only batches. Both are listened
|
|
44
|
+
// for, because the bundle in the browser and the installed desktop
|
|
45
|
+
// app are updated separately; only one of them ever fires.
|
|
46
|
+
ids.push(bridge.addListener(SCAN_BATCH_EVENT, (batch) => {
|
|
47
|
+
for (const event of batch)
|
|
48
|
+
callback(event);
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
remove: async () => {
|
|
53
|
+
for (const id of ids)
|
|
54
|
+
bridge.removeListener(id);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
return plugin;
|
|
60
|
+
}
|
|
61
|
+
|
|
7
62
|
const RFID = core.registerPlugin('RFID', {
|
|
8
63
|
web: () => Promise.resolve().then(function () { return web; }).then(m => new m.RFIDWeb()),
|
|
9
64
|
electron: () => {
|
|
10
65
|
var _a, _b;
|
|
11
|
-
const
|
|
12
|
-
if (!
|
|
66
|
+
const bridge = (_b = (_a = window.CapacitorCustomPlatform) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.RFID;
|
|
67
|
+
if (!bridge) {
|
|
13
68
|
throw new Error('RFID is not registered in the Electron runtime. Register the driver in electron-plugins.js.');
|
|
14
69
|
}
|
|
15
|
-
return
|
|
70
|
+
return withListenerHandles(bridge);
|
|
16
71
|
},
|
|
17
72
|
});
|
|
18
73
|
|
|
@@ -35,6 +90,24 @@ class RFIDWeb extends core.WebPlugin {
|
|
|
35
90
|
async getCapabilities() {
|
|
36
91
|
throw this.unimplemented(NO_READER_ON_WEB);
|
|
37
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Not `not-found`: that state tells the operator to check the cable, and
|
|
95
|
+
* there is no cable to check in a browser. The rejection carries the one
|
|
96
|
+
* useful sentence — open the desktop app or the handheld.
|
|
97
|
+
*/
|
|
98
|
+
async getConnectionState() {
|
|
99
|
+
throw this.unimplemented(NO_READER_ON_WEB);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Not an empty list: "no readers plugged in" would send the operator to look
|
|
103
|
+
* for a cable, and the browser has no serial ports to look at.
|
|
104
|
+
*/
|
|
105
|
+
async listReaderPorts() {
|
|
106
|
+
throw this.unimplemented(NO_READER_ON_WEB);
|
|
107
|
+
}
|
|
108
|
+
async selectReaderPort() {
|
|
109
|
+
throw this.unimplemented(NO_READER_ON_WEB);
|
|
110
|
+
}
|
|
38
111
|
async startScan() {
|
|
39
112
|
throw this.unimplemented(NO_READER_ON_WEB);
|
|
40
113
|
}
|
package/dist/plugin.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst RFID = registerPlugin('RFID', {\n web: () => import('./web').then(m => new m.RFIDWeb()),\n electron: () => {\n var _a, _b;\n const plugin = (_b = (_a = window.CapacitorCustomPlatform) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.RFID;\n if (!plugin) {\n throw new Error('RFID is not registered in the Electron runtime. Register the driver in electron-plugins.js.');\n }\n return plugin;\n },\n});\nexport * from './definitions';\nexport { RFID };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nconst NO_READER_ON_WEB = 'No RFID Reader in the browser. Use the desktop app (ox-desktop) or the Android handheld.';\nexport class RFIDWeb extends WebPlugin {\n /**\n * The one method the browser can answer truthfully. Everything else rejects:\n * a silent `resolve` makes the UI report a success that never happened.\n */\n async isConnected() {\n return { connected: false };\n }\n /**\n * Events never fire without a Reader, so registering a listener here would be\n * the same silent lie as a resolving `startScan()`.\n */\n async addListener() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getCapabilities() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async startScan() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async stopScan() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async clearData() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getScanData() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getOutputPower() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setOutputPower() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getRange() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setRange() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getQueryMode() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setQueryMode() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getReaderType() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getFirmwareVersion() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async writeEpc() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async writeEpcString() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async startSearch() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async stopSearch() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["esm/electron-bridge.js","esm/index.js","esm/web.js"],"sourcesContent":["const SCAN_EVENT = 'onScanEvent';\n/**\n * The Electron main process sends the tags it read in one message per 250 ms\n * window instead of one per frame — a single tag is read about 44 times a\n * second. The contract does not change: the array is unrolled here, so a\n * listener still gets one tag per call.\n */\nconst SCAN_BATCH_EVENT = 'onScanEventBatch';\n/**\n * On native platforms Capacitor wraps the `addListener` result into a\n * `PluginListenerHandle` itself (`addListenerNative`), but only when\n * `PluginHeaders` are present. Electron has none, so the bridge's raw id\n * string reaches the UI as-is and `handle.remove()` is missing: the listener\n * is never removed, and scanning does not start the second time the modal\n * opens.\n *\n * Do not wrap it with a `Proxy`. Methods of an object exposed through\n * `contextBridge` arrive as `writable: false, configurable: false`, and for\n * such a property a `get` trap must return **that exact value** — even a\n * bound copy is rejected. Otherwise the engine throws the error we saw on\n * the device:\n * TypeError: 'get' on proxy: property 'startScan' is a read-only and\n * non-configurable data property on the proxy target but the proxy did\n * not return its actual value\n * So the bridge is used as the prototype instead: the other methods are\n * found on it as usual, and only `addListener` is defined on top.\n */\nexport function withListenerHandles(bridge) {\n const plugin = Object.create(bridge);\n // A plain `plugin.addListener = ...` does not work: the prototype property\n // is `writable: false`, so [[Set]] blocks it.\n Object.defineProperty(plugin, 'addListener', {\n value: async (eventName, callback) => {\n const ids = [bridge.addListener(eventName, callback)];\n if (eventName === SCAN_EVENT) {\n // A desktop app older than the batch sends one message per tag on\n // `onScanEvent`, a newer one sends only batches. Both are listened\n // for, because the bundle in the browser and the installed desktop\n // app are updated separately; only one of them ever fires.\n ids.push(bridge.addListener(SCAN_BATCH_EVENT, (batch) => {\n for (const event of batch)\n callback(event);\n }));\n }\n return {\n remove: async () => {\n for (const id of ids)\n bridge.removeListener(id);\n },\n };\n },\n });\n return plugin;\n}\n//# sourceMappingURL=electron-bridge.js.map","import { registerPlugin } from '@capacitor/core';\nimport { withListenerHandles } from './electron-bridge';\nconst RFID = registerPlugin('RFID', {\n web: () => import('./web').then(m => new m.RFIDWeb()),\n electron: () => {\n var _a, _b;\n const bridge = (_b = (_a = window.CapacitorCustomPlatform) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.RFID;\n if (!bridge) {\n throw new Error('RFID is not registered in the Electron runtime. Register the driver in electron-plugins.js.');\n }\n return withListenerHandles(bridge);\n },\n});\nexport * from './definitions';\nexport { RFID };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nconst NO_READER_ON_WEB = 'No RFID Reader in the browser. Use the desktop app (ox-desktop) or the Android handheld.';\nexport class RFIDWeb extends WebPlugin {\n /**\n * The one method the browser can answer truthfully. Everything else rejects:\n * a silent `resolve` makes the UI report a success that never happened.\n */\n async isConnected() {\n return { connected: false };\n }\n /**\n * Events never fire without a Reader, so registering a listener here would be\n * the same silent lie as a resolving `startScan()`.\n */\n async addListener() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getCapabilities() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n /**\n * Not `not-found`: that state tells the operator to check the cable, and\n * there is no cable to check in a browser. The rejection carries the one\n * useful sentence — open the desktop app or the handheld.\n */\n async getConnectionState() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n /**\n * Not an empty list: \"no readers plugged in\" would send the operator to look\n * for a cable, and the browser has no serial ports to look at.\n */\n async listReaderPorts() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async selectReaderPort() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async startScan() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async stopScan() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async clearData() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getScanData() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getOutputPower() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setOutputPower() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getRange() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setRange() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getQueryMode() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setQueryMode() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getReaderType() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getFirmwareVersion() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async writeEpc() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async writeEpcString() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async startSearch() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async stopSearch() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
|
package/dist/plugin.js
CHANGED
|
@@ -1,15 +1,70 @@
|
|
|
1
1
|
var capacitorExample = (function (exports, core) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
const SCAN_EVENT = 'onScanEvent';
|
|
5
|
+
/**
|
|
6
|
+
* The Electron main process sends the tags it read in one message per 250 ms
|
|
7
|
+
* window instead of one per frame — a single tag is read about 44 times a
|
|
8
|
+
* second. The contract does not change: the array is unrolled here, so a
|
|
9
|
+
* listener still gets one tag per call.
|
|
10
|
+
*/
|
|
11
|
+
const SCAN_BATCH_EVENT = 'onScanEventBatch';
|
|
12
|
+
/**
|
|
13
|
+
* On native platforms Capacitor wraps the `addListener` result into a
|
|
14
|
+
* `PluginListenerHandle` itself (`addListenerNative`), but only when
|
|
15
|
+
* `PluginHeaders` are present. Electron has none, so the bridge's raw id
|
|
16
|
+
* string reaches the UI as-is and `handle.remove()` is missing: the listener
|
|
17
|
+
* is never removed, and scanning does not start the second time the modal
|
|
18
|
+
* opens.
|
|
19
|
+
*
|
|
20
|
+
* Do not wrap it with a `Proxy`. Methods of an object exposed through
|
|
21
|
+
* `contextBridge` arrive as `writable: false, configurable: false`, and for
|
|
22
|
+
* such a property a `get` trap must return **that exact value** — even a
|
|
23
|
+
* bound copy is rejected. Otherwise the engine throws the error we saw on
|
|
24
|
+
* the device:
|
|
25
|
+
* TypeError: 'get' on proxy: property 'startScan' is a read-only and
|
|
26
|
+
* non-configurable data property on the proxy target but the proxy did
|
|
27
|
+
* not return its actual value
|
|
28
|
+
* So the bridge is used as the prototype instead: the other methods are
|
|
29
|
+
* found on it as usual, and only `addListener` is defined on top.
|
|
30
|
+
*/
|
|
31
|
+
function withListenerHandles(bridge) {
|
|
32
|
+
const plugin = Object.create(bridge);
|
|
33
|
+
// A plain `plugin.addListener = ...` does not work: the prototype property
|
|
34
|
+
// is `writable: false`, so [[Set]] blocks it.
|
|
35
|
+
Object.defineProperty(plugin, 'addListener', {
|
|
36
|
+
value: async (eventName, callback) => {
|
|
37
|
+
const ids = [bridge.addListener(eventName, callback)];
|
|
38
|
+
if (eventName === SCAN_EVENT) {
|
|
39
|
+
// A desktop app older than the batch sends one message per tag on
|
|
40
|
+
// `onScanEvent`, a newer one sends only batches. Both are listened
|
|
41
|
+
// for, because the bundle in the browser and the installed desktop
|
|
42
|
+
// app are updated separately; only one of them ever fires.
|
|
43
|
+
ids.push(bridge.addListener(SCAN_BATCH_EVENT, (batch) => {
|
|
44
|
+
for (const event of batch)
|
|
45
|
+
callback(event);
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
remove: async () => {
|
|
50
|
+
for (const id of ids)
|
|
51
|
+
bridge.removeListener(id);
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
return plugin;
|
|
57
|
+
}
|
|
58
|
+
|
|
4
59
|
const RFID = core.registerPlugin('RFID', {
|
|
5
60
|
web: () => Promise.resolve().then(function () { return web; }).then(m => new m.RFIDWeb()),
|
|
6
61
|
electron: () => {
|
|
7
62
|
var _a, _b;
|
|
8
|
-
const
|
|
9
|
-
if (!
|
|
63
|
+
const bridge = (_b = (_a = window.CapacitorCustomPlatform) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.RFID;
|
|
64
|
+
if (!bridge) {
|
|
10
65
|
throw new Error('RFID is not registered in the Electron runtime. Register the driver in electron-plugins.js.');
|
|
11
66
|
}
|
|
12
|
-
return
|
|
67
|
+
return withListenerHandles(bridge);
|
|
13
68
|
},
|
|
14
69
|
});
|
|
15
70
|
|
|
@@ -32,6 +87,24 @@ var capacitorExample = (function (exports, core) {
|
|
|
32
87
|
async getCapabilities() {
|
|
33
88
|
throw this.unimplemented(NO_READER_ON_WEB);
|
|
34
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Not `not-found`: that state tells the operator to check the cable, and
|
|
92
|
+
* there is no cable to check in a browser. The rejection carries the one
|
|
93
|
+
* useful sentence — open the desktop app or the handheld.
|
|
94
|
+
*/
|
|
95
|
+
async getConnectionState() {
|
|
96
|
+
throw this.unimplemented(NO_READER_ON_WEB);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Not an empty list: "no readers plugged in" would send the operator to look
|
|
100
|
+
* for a cable, and the browser has no serial ports to look at.
|
|
101
|
+
*/
|
|
102
|
+
async listReaderPorts() {
|
|
103
|
+
throw this.unimplemented(NO_READER_ON_WEB);
|
|
104
|
+
}
|
|
105
|
+
async selectReaderPort() {
|
|
106
|
+
throw this.unimplemented(NO_READER_ON_WEB);
|
|
107
|
+
}
|
|
35
108
|
async startScan() {
|
|
36
109
|
throw this.unimplemented(NO_READER_ON_WEB);
|
|
37
110
|
}
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst RFID = registerPlugin('RFID', {\n web: () => import('./web').then(m => new m.RFIDWeb()),\n electron: () => {\n var _a, _b;\n const plugin = (_b = (_a = window.CapacitorCustomPlatform) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.RFID;\n if (!plugin) {\n throw new Error('RFID is not registered in the Electron runtime. Register the driver in electron-plugins.js.');\n }\n return plugin;\n },\n});\nexport * from './definitions';\nexport { RFID };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nconst NO_READER_ON_WEB = 'No RFID Reader in the browser. Use the desktop app (ox-desktop) or the Android handheld.';\nexport class RFIDWeb extends WebPlugin {\n /**\n * The one method the browser can answer truthfully. Everything else rejects:\n * a silent `resolve` makes the UI report a success that never happened.\n */\n async isConnected() {\n return { connected: false };\n }\n /**\n * Events never fire without a Reader, so registering a listener here would be\n * the same silent lie as a resolving `startScan()`.\n */\n async addListener() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getCapabilities() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async startScan() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async stopScan() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async clearData() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getScanData() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getOutputPower() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setOutputPower() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getRange() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setRange() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getQueryMode() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setQueryMode() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getReaderType() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getFirmwareVersion() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async writeEpc() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async writeEpcString() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async startSearch() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async stopSearch() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/electron-bridge.js","esm/index.js","esm/web.js"],"sourcesContent":["const SCAN_EVENT = 'onScanEvent';\n/**\n * The Electron main process sends the tags it read in one message per 250 ms\n * window instead of one per frame — a single tag is read about 44 times a\n * second. The contract does not change: the array is unrolled here, so a\n * listener still gets one tag per call.\n */\nconst SCAN_BATCH_EVENT = 'onScanEventBatch';\n/**\n * On native platforms Capacitor wraps the `addListener` result into a\n * `PluginListenerHandle` itself (`addListenerNative`), but only when\n * `PluginHeaders` are present. Electron has none, so the bridge's raw id\n * string reaches the UI as-is and `handle.remove()` is missing: the listener\n * is never removed, and scanning does not start the second time the modal\n * opens.\n *\n * Do not wrap it with a `Proxy`. Methods of an object exposed through\n * `contextBridge` arrive as `writable: false, configurable: false`, and for\n * such a property a `get` trap must return **that exact value** — even a\n * bound copy is rejected. Otherwise the engine throws the error we saw on\n * the device:\n * TypeError: 'get' on proxy: property 'startScan' is a read-only and\n * non-configurable data property on the proxy target but the proxy did\n * not return its actual value\n * So the bridge is used as the prototype instead: the other methods are\n * found on it as usual, and only `addListener` is defined on top.\n */\nexport function withListenerHandles(bridge) {\n const plugin = Object.create(bridge);\n // A plain `plugin.addListener = ...` does not work: the prototype property\n // is `writable: false`, so [[Set]] blocks it.\n Object.defineProperty(plugin, 'addListener', {\n value: async (eventName, callback) => {\n const ids = [bridge.addListener(eventName, callback)];\n if (eventName === SCAN_EVENT) {\n // A desktop app older than the batch sends one message per tag on\n // `onScanEvent`, a newer one sends only batches. Both are listened\n // for, because the bundle in the browser and the installed desktop\n // app are updated separately; only one of them ever fires.\n ids.push(bridge.addListener(SCAN_BATCH_EVENT, (batch) => {\n for (const event of batch)\n callback(event);\n }));\n }\n return {\n remove: async () => {\n for (const id of ids)\n bridge.removeListener(id);\n },\n };\n },\n });\n return plugin;\n}\n//# sourceMappingURL=electron-bridge.js.map","import { registerPlugin } from '@capacitor/core';\nimport { withListenerHandles } from './electron-bridge';\nconst RFID = registerPlugin('RFID', {\n web: () => import('./web').then(m => new m.RFIDWeb()),\n electron: () => {\n var _a, _b;\n const bridge = (_b = (_a = window.CapacitorCustomPlatform) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.RFID;\n if (!bridge) {\n throw new Error('RFID is not registered in the Electron runtime. Register the driver in electron-plugins.js.');\n }\n return withListenerHandles(bridge);\n },\n});\nexport * from './definitions';\nexport { RFID };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nconst NO_READER_ON_WEB = 'No RFID Reader in the browser. Use the desktop app (ox-desktop) or the Android handheld.';\nexport class RFIDWeb extends WebPlugin {\n /**\n * The one method the browser can answer truthfully. Everything else rejects:\n * a silent `resolve` makes the UI report a success that never happened.\n */\n async isConnected() {\n return { connected: false };\n }\n /**\n * Events never fire without a Reader, so registering a listener here would be\n * the same silent lie as a resolving `startScan()`.\n */\n async addListener() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getCapabilities() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n /**\n * Not `not-found`: that state tells the operator to check the cable, and\n * there is no cable to check in a browser. The rejection carries the one\n * useful sentence — open the desktop app or the handheld.\n */\n async getConnectionState() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n /**\n * Not an empty list: \"no readers plugged in\" would send the operator to look\n * for a cable, and the browser has no serial ports to look at.\n */\n async listReaderPorts() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async selectReaderPort() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async startScan() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async stopScan() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async clearData() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getScanData() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getOutputPower() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setOutputPower() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getRange() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setRange() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getQueryMode() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async setQueryMode() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getReaderType() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async getFirmwareVersion() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async writeEpc() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async writeEpcString() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async startSearch() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n async stopSearch() {\n throw this.unimplemented(NO_READER_ON_WEB);\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "capacitor-rfid-plugin-ox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "rfid read-write",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.js",
|
|
42
42
|
"clean": "rimraf ./dist",
|
|
43
43
|
"watch": "tsc --watch",
|
|
44
|
-
"prepublishOnly": "npm run build"
|
|
44
|
+
"prepublishOnly": "npm run build",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest"
|
|
45
47
|
},
|
|
46
48
|
"devDependencies": {
|
|
47
49
|
"@capacitor/android": "^6.0.0",
|
|
@@ -57,7 +59,8 @@
|
|
|
57
59
|
"rimraf": "^3.0.2",
|
|
58
60
|
"rollup": "^2.32.0",
|
|
59
61
|
"swiftlint": "^1.0.1",
|
|
60
|
-
"typescript": "~4.1.5"
|
|
62
|
+
"typescript": "~4.1.5",
|
|
63
|
+
"vitest": "^0.34.6"
|
|
61
64
|
},
|
|
62
65
|
"peerDependencies": {
|
|
63
66
|
"@capacitor/core": "^6.0.0"
|