@signosoft/signpad-js 0.5.2 → 0.6.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 +41 -17
- package/dist/index.d.ts +72 -5
- package/dist/signosoft-signpad.js +1185 -1056
- package/dist/signosoft-signpad.umd.cjs +35 -35
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -59,14 +59,13 @@ Without a valid lease, the component can still render, but driver initialization
|
|
|
59
59
|
async function fetchLease() {
|
|
60
60
|
try {
|
|
61
61
|
const response = await fetch(
|
|
62
|
-
"https://test.signosoft.com/api/v1/driver/
|
|
62
|
+
"https://test.signosoft.com/api/v1/public/driver-leases/create",
|
|
63
63
|
{
|
|
64
64
|
method: "POST",
|
|
65
65
|
headers: { "Content-Type": "application/json" },
|
|
66
66
|
body: JSON.stringify({
|
|
67
|
-
|
|
67
|
+
token: "YOUR-LICENSE-TOKEN",
|
|
68
68
|
validityHours: 24,
|
|
69
|
-
port: 4204,
|
|
70
69
|
}),
|
|
71
70
|
},
|
|
72
71
|
);
|
|
@@ -245,14 +244,13 @@ export class AppComponent implements AfterViewInit {
|
|
|
245
244
|
public async fetchLease(): Promise<any> {
|
|
246
245
|
try {
|
|
247
246
|
const response = await fetch(
|
|
248
|
-
"https://test.signosoft.com/api/v1/driver/
|
|
247
|
+
"https://test.signosoft.com/api/v1/public/driver-leases/create",
|
|
249
248
|
{
|
|
250
249
|
method: "POST",
|
|
251
250
|
headers: { "Content-Type": "application/json" },
|
|
252
251
|
body: JSON.stringify({
|
|
253
|
-
|
|
252
|
+
token: "YOUR-LICENSE-TOKEN",
|
|
254
253
|
validityHours: 24,
|
|
255
|
-
port: 4204,
|
|
256
254
|
}),
|
|
257
255
|
},
|
|
258
256
|
);
|
|
@@ -331,14 +329,13 @@ import type { SignpadConfig } from "@signosoft/signpad-js";
|
|
|
331
329
|
async function fetchLease() {
|
|
332
330
|
try {
|
|
333
331
|
const response = await fetch(
|
|
334
|
-
"https://test.signosoft.com/api/v1/driver/
|
|
332
|
+
"https://test.signosoft.com/api/v1/public/driver-leases/create",
|
|
335
333
|
{
|
|
336
334
|
method: "POST",
|
|
337
335
|
headers: { "Content-Type": "application/json" },
|
|
338
336
|
body: JSON.stringify({
|
|
339
|
-
|
|
337
|
+
token: "YOUR-LICENSE-TOKEN",
|
|
340
338
|
validityHours: 24,
|
|
341
|
-
port: 4204,
|
|
342
339
|
}),
|
|
343
340
|
},
|
|
344
341
|
);
|
|
@@ -439,13 +436,12 @@ const signpadConfig = ref<SignpadConfig>({ lease: undefined });
|
|
|
439
436
|
|
|
440
437
|
const fetchLease = async () => {
|
|
441
438
|
try {
|
|
442
|
-
const response = await fetch("https://test.signosoft.com/api/v1/driver/
|
|
439
|
+
const response = await fetch("https://test.signosoft.com/api/v1/public/driver-leases/create", {
|
|
443
440
|
method: "POST",
|
|
444
441
|
headers: { "Content-Type": "application/json" },
|
|
445
442
|
body: JSON.stringify({
|
|
446
|
-
|
|
443
|
+
token: "YOUR-LICENSE-TOKEN",
|
|
447
444
|
validityHours: 24,
|
|
448
|
-
port: 4204,
|
|
449
445
|
}),
|
|
450
446
|
});
|
|
451
447
|
|
|
@@ -526,14 +522,13 @@ pad.config = {
|
|
|
526
522
|
const fetchLease = async () => {
|
|
527
523
|
try {
|
|
528
524
|
const response = await fetch(
|
|
529
|
-
"https://test.signosoft.com/api/v1/driver/
|
|
525
|
+
"https://test.signosoft.com/api/v1/public/driver-leases/create",
|
|
530
526
|
{
|
|
531
527
|
method: "POST",
|
|
532
528
|
headers: { "Content-Type": "application/json" },
|
|
533
529
|
body: JSON.stringify({
|
|
534
|
-
|
|
530
|
+
token: "YOUR-LICENSE-TOKEN",
|
|
535
531
|
validityHours: 24,
|
|
536
|
-
port: 4204,
|
|
537
532
|
}),
|
|
538
533
|
},
|
|
539
534
|
);
|
|
@@ -676,6 +671,7 @@ The complete list of keys that can be translated is maintained in `src/i18n/en.j
|
|
|
676
671
|
| `CONNECTION_ERROR` | Connection error. |
|
|
677
672
|
| `ERROR_DISCONNECTION` | Error during disconnection. |
|
|
678
673
|
| `ERROR_INSTANTIATING_DRIVER` | Error instantiating driver. |
|
|
674
|
+
| `INSUFFICIENT_TOKENS` | Not enough tokens to sign. Reconnecting… |
|
|
679
675
|
| `INVALID_LICENSE_KEY` | Invalid license key. |
|
|
680
676
|
| `READY_TO_CONNECT` | Ready to connect. |
|
|
681
677
|
| `SIGNPAD_DETECTED` | Signpad detected. Click 'Connect Signpad' to begin. |
|
|
@@ -711,10 +707,28 @@ Standard event listeners triggered _after_ specific actions. Useful for observin
|
|
|
711
707
|
| `onOk` | `event: CustomEvent<ISignatureConfirmationData>` | Dispatched when signature is confirmed. |
|
|
712
708
|
| `onClear` | `event: CustomEvent<void>` | Dispatched when the canvas has been cleared. |
|
|
713
709
|
| `onCancel` | `event: CustomEvent<void>` | Dispatched when the user aborts the session. |
|
|
714
|
-
| `onError` | `event: CustomEvent<
|
|
710
|
+
| `onError` | `event: CustomEvent<ISignpadErrorDetail>` | Dispatched on critical failures (lease, driver, connection, billing, etc.). |
|
|
715
711
|
|
|
716
712
|
> `actionHandlers` and `eventCallbacks` are separate hooks and can both be configured.
|
|
717
713
|
|
|
714
|
+
#### 🚨 `onError` payload (`ISignpadErrorDetail`)
|
|
715
|
+
|
|
716
|
+
```typescript
|
|
717
|
+
{
|
|
718
|
+
category: SignpadErrorCategory; // BILLING_DENIED | NETWORK | OTHER
|
|
719
|
+
message: string; // error.message, for convenience
|
|
720
|
+
error: Error; // the original error
|
|
721
|
+
}
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
`category` also drives automatic recovery:
|
|
725
|
+
|
|
726
|
+
- **`BILLING_DENIED`** — the lease has run out of signing credits/tokens. Signing automatically restarts a few seconds after the error is shown.
|
|
727
|
+
- **`OTHER`** — any other recoverable failure (e.g. a driver hiccup, a cancelled device picker). Signing automatically restarts the same way as `BILLING_DENIED`.
|
|
728
|
+
- **`NETWORK`** — a connectivity problem (lease fetch failed, device physically disconnected, origin validation failed). The error stays shown; signing does **not** auto-restart, since retrying on a timer can't fix a network or configuration problem — the user (or your app) must retry manually, e.g. via `connect()`.
|
|
729
|
+
|
|
730
|
+
> **Migration note (breaking payload shape change):** `event.detail` used to be the raw `Error`. It is now `ISignpadErrorDetail`; use `event.detail.error` for the original `Error` instance. `event.detail.message` still works unchanged.
|
|
731
|
+
|
|
718
732
|
---
|
|
719
733
|
|
|
720
734
|
### 💡 Example Implementation
|
|
@@ -923,7 +937,17 @@ The component progresses through a finite set of states, exposed via the `Signpa
|
|
|
923
937
|
| `PROCESSING_CANCEL` | `"processing_cancel"` | Cancel action is being processed. |
|
|
924
938
|
| `DISCONNECTING` | `"disconnecting"` | Disconnect in progress. |
|
|
925
939
|
| `DISCONNECTED` | `"disconnected"` | Component is idle and disconnected. |
|
|
926
|
-
| `ERROR` | `"error"` | An
|
|
940
|
+
| `ERROR` | `"error"` | An error occurred (see `onError` callback). Signing automatically restarts a few seconds later unless the error's `category` is `NETWORK`. |
|
|
941
|
+
|
|
942
|
+
### 🚨 `SignpadErrorCategory`
|
|
943
|
+
|
|
944
|
+
Also importable from `@signosoft/signpad-js`, carried on the `onError` payload (see [`onError` payload](#-onerror-payload-isignpaderrordetail) above):
|
|
945
|
+
|
|
946
|
+
| Value | Value string | Auto-restarts signing? |
|
|
947
|
+
| :--------------- | :------------------ | :---------------------- |
|
|
948
|
+
| `BILLING_DENIED` | `"billing_denied"` | Yes |
|
|
949
|
+
| `NETWORK` | `"network"` | No |
|
|
950
|
+
| `OTHER` | `"other"` | Yes |
|
|
927
951
|
|
|
928
952
|
---
|
|
929
953
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ConnectionMode } from '@signosoft/tablet-driver';
|
|
1
2
|
import { CSSResult } from 'lit';
|
|
2
3
|
import { LitElement } from 'lit';
|
|
3
4
|
import { TemplateResult } from 'lit-html';
|
|
@@ -176,11 +177,12 @@ declare class ConnectionManager {
|
|
|
176
177
|
/**
|
|
177
178
|
* Initiates the connection process to a physical device or a mouse fallback.
|
|
178
179
|
*
|
|
179
|
-
* @param autoConnect -
|
|
180
|
+
* @param autoConnect - Connect mode: "manual" opens the browser device selection
|
|
181
|
+
* dialog; "auto"/"hotplug" attempt already-authorized devices silently.
|
|
180
182
|
* @param allowFallback - If true, enables mouse/pointer input if no physical device is found.
|
|
181
183
|
* @returns A promise resolving to true if connection (or fallback) was successful.
|
|
182
184
|
*/
|
|
183
|
-
connect(autoConnect?:
|
|
185
|
+
connect(autoConnect?: ConnectionMode, allowFallback?: boolean): Promise<boolean>;
|
|
184
186
|
/**
|
|
185
187
|
* Terminates the connection with the device and cleans up the driver instance.
|
|
186
188
|
* @returns Resolves when disconnection completes.
|
|
@@ -239,6 +241,20 @@ declare class ConnectionManager {
|
|
|
239
241
|
* @returns Resolves when the driver is initialized.
|
|
240
242
|
*/
|
|
241
243
|
initWithLease(lease: any): Promise<void>;
|
|
244
|
+
/**
|
|
245
|
+
* Called by the driver when the lease has run out of signing credits.
|
|
246
|
+
* @param detail - Driver-provided description of the denial.
|
|
247
|
+
* @returns Always false — declines the driver's own retry; signpad-js's
|
|
248
|
+
* auto-restart (triggered by the ERROR transition below) handles recovery.
|
|
249
|
+
*/
|
|
250
|
+
private handleBillingDenied;
|
|
251
|
+
/**
|
|
252
|
+
* Called by the driver when the billing check itself fails (e.g. the
|
|
253
|
+
* billing server is unreachable). Treated as a network error.
|
|
254
|
+
* @param detail - Driver-provided description of the failure.
|
|
255
|
+
* @returns Always false — see handleBillingDenied.
|
|
256
|
+
*/
|
|
257
|
+
private handleBillingError;
|
|
242
258
|
isFallback(deviceInfo: any | null, isDeviceConnected: boolean, includeDisconnected: boolean): boolean;
|
|
243
259
|
/**
|
|
244
260
|
* Normalizes device info to always include deviceName.
|
|
@@ -286,7 +302,7 @@ export declare interface IEventCallbacks {
|
|
|
286
302
|
onOk?: (event: CustomEvent<ISignatureConfirmationData>) => void;
|
|
287
303
|
onClear?: (event: CustomEvent<void>) => void;
|
|
288
304
|
onCancel?: (event: CustomEvent<void>) => void;
|
|
289
|
-
onError?: (event: CustomEvent<
|
|
305
|
+
onError?: (event: CustomEvent<ISignpadErrorDetail>) => void;
|
|
290
306
|
}
|
|
291
307
|
|
|
292
308
|
export declare interface ILanguageOptions {
|
|
@@ -358,6 +374,12 @@ export declare interface ISignatureTabletMeta {
|
|
|
358
374
|
[key: string]: any;
|
|
359
375
|
}
|
|
360
376
|
|
|
377
|
+
export declare interface ISignpadErrorDetail {
|
|
378
|
+
category: SignpadErrorCategory;
|
|
379
|
+
message: string;
|
|
380
|
+
error: Error;
|
|
381
|
+
}
|
|
382
|
+
|
|
361
383
|
export declare interface ITranslationSet {
|
|
362
384
|
[key: string]: string;
|
|
363
385
|
}
|
|
@@ -520,7 +542,8 @@ export declare class SignosoftSignpad extends LitElement {
|
|
|
520
542
|
dispatch(name: string, detail?: any): void;
|
|
521
543
|
/**
|
|
522
544
|
* Attempts to establish a connection with a signature tablet.
|
|
523
|
-
* @param autoConnect -
|
|
545
|
+
* @param autoConnect - Connect mode: "manual" opens the browser HID picker;
|
|
546
|
+
* "auto"/"hotplug" silently try already-authorized devices (see `ConnectionMode`).
|
|
524
547
|
* @param allowFallback - If true, enables mouse/touch signing if no device is found.
|
|
525
548
|
* @returns A promise resolving to true if connection (or fallback) succeeded.
|
|
526
549
|
*/
|
|
@@ -560,8 +583,24 @@ export declare class SignosoftSignpad extends LitElement {
|
|
|
560
583
|
* - if physical is not available, allow fallback as a secondary attempt
|
|
561
584
|
*/
|
|
562
585
|
connect: () => Promise<void>;
|
|
586
|
+
/**
|
|
587
|
+
* If currently in mouse fallback, tears that session down seamlessly
|
|
588
|
+
* (no DISCONNECTED UI flash) so a physical-device connect attempt can
|
|
589
|
+
* proceed cleanly.
|
|
590
|
+
*/
|
|
563
591
|
private prepareForManualConnect;
|
|
592
|
+
/**
|
|
593
|
+
* First step of the manual `connect()` flow: silently retries an
|
|
594
|
+
* already-authorized device (no HID picker) using "auto" mode.
|
|
595
|
+
* `allowFallback=false` ensures we only treat a real physical reconnect as success.
|
|
596
|
+
*/
|
|
564
597
|
private tryAuthorizedManualConnect;
|
|
598
|
+
/**
|
|
599
|
+
* Second step of the manual `connect()` flow, run only when the silent
|
|
600
|
+
* attempt above fails: opens the browser HID picker ("manual" mode) so
|
|
601
|
+
* the user can grant access to a new device. If the user cancels or no
|
|
602
|
+
* device is selected, falls back to one more silent "auto" attempt.
|
|
603
|
+
*/
|
|
565
604
|
private tryInteractiveManualConnectFallback;
|
|
566
605
|
/**
|
|
567
606
|
* UI disconnect action: delegates to the public disconnect method.
|
|
@@ -611,6 +650,19 @@ export declare class SignosoftSignpad extends LitElement {
|
|
|
611
650
|
private shouldScheduleImmediateRetry;
|
|
612
651
|
private scheduleAutoConnectRetry;
|
|
613
652
|
private clearAutoConnectQueue;
|
|
653
|
+
/**
|
|
654
|
+
* Schedules signing to restart automatically after a BILLING_DENIED/OTHER
|
|
655
|
+
* error, so the flow recovers without requiring a manual reconnect.
|
|
656
|
+
* NETWORK errors never reach this — they stay shown until the user retries.
|
|
657
|
+
* @param delayMs - How long to keep the error visible before restarting.
|
|
658
|
+
*/
|
|
659
|
+
private scheduleErrorAutoRestart;
|
|
660
|
+
/**
|
|
661
|
+
* Restarts the signing session after an auto-recoverable error, respecting
|
|
662
|
+
* the connect/disconnect reentrancy lock so it never races a concurrent
|
|
663
|
+
* manual connect/disconnect or hotplug transition.
|
|
664
|
+
*/
|
|
665
|
+
private restartSigningAfterError;
|
|
614
666
|
private delay;
|
|
615
667
|
/**
|
|
616
668
|
* Disconnects current session without transitioning through DISCONNECTED UI.
|
|
@@ -657,6 +709,12 @@ export declare interface SignpadConfig {
|
|
|
657
709
|
eventCallbacks?: IEventCallbacks;
|
|
658
710
|
}
|
|
659
711
|
|
|
712
|
+
export declare enum SignpadErrorCategory {
|
|
713
|
+
BILLING_DENIED = "billing_denied",
|
|
714
|
+
NETWORK = "network",
|
|
715
|
+
OTHER = "other"
|
|
716
|
+
}
|
|
717
|
+
|
|
660
718
|
export declare enum SignpadEventType {
|
|
661
719
|
SIGN_PEN = "sign-pen",
|
|
662
720
|
SIGN_OK = "sign-ok",
|
|
@@ -683,6 +741,7 @@ export declare enum SignpadMessage {
|
|
|
683
741
|
CONNECTION_ERROR = "CONNECTION_ERROR",
|
|
684
742
|
ERROR_DISCONNECTION = "ERROR_DISCONNECTION",
|
|
685
743
|
ERROR_INSTANTIATING_DRIVER = "ERROR_INSTANTIATING_DRIVER",
|
|
744
|
+
INSUFFICIENT_TOKENS = "INSUFFICIENT_TOKENS",
|
|
686
745
|
INVALID_LICENSE_KEY = "INVALID_LICENSE_KEY",
|
|
687
746
|
READY_TO_CONNECT = "READY_TO_CONNECT",
|
|
688
747
|
SIGNPAD_DETECTED = "SIGNPAD_DETECTED",
|
|
@@ -781,7 +840,15 @@ declare class StateManager {
|
|
|
781
840
|
* @param error - Optional error object if transitioning to an ERROR state.
|
|
782
841
|
* @returns void
|
|
783
842
|
*/
|
|
784
|
-
transitionTo(newState: SignpadState, messageKey?: string, error?: Error): void;
|
|
843
|
+
transitionTo(newState: SignpadState, messageKey?: string, error?: Error, category?: SignpadErrorCategory): void;
|
|
844
|
+
/**
|
|
845
|
+
* Heuristically classifies an error for auto-recovery decisions.
|
|
846
|
+
* Explicit categories (e.g. from billing hooks) should be passed to
|
|
847
|
+
* transitionTo directly rather than relying on this fallback.
|
|
848
|
+
* @param error - The error to classify.
|
|
849
|
+
* @returns The inferred error category.
|
|
850
|
+
*/
|
|
851
|
+
private classifyError;
|
|
785
852
|
/**
|
|
786
853
|
* Updates the internal drawing flag. Triggers a UI update if the value changes.
|
|
787
854
|
* @param started - Boolean indicating if the user has started drawing.
|