@licenseseat/js 0.3.1 → 0.4.2
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 +156 -1
- package/dist/index.bundled.js +2775 -0
- package/dist/index.js +467 -13
- package/dist/types/LicenseSeat.d.ts +40 -7
- package/dist/types/LicenseSeat.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +16 -0
- package/dist/types/telemetry.d.ts.map +1 -0
- package/dist/types/types.d.ts +33 -0
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/LicenseSeat.js +136 -13
- package/src/global.d.ts +23 -0
- package/src/index.js +6 -2
- package/src/telemetry.js +518 -0
- package/src/types.js +12 -0
package/README.md
CHANGED
|
@@ -13,6 +13,8 @@ The official JavaScript/TypeScript SDK for [LicenseSeat](https://licenseseat.com
|
|
|
13
13
|
- **License activation & deactivation** – Activate licenses with automatic device fingerprinting
|
|
14
14
|
- **Online & offline validation** – Validate licenses with optional offline fallback
|
|
15
15
|
- **Entitlement checking** – Check feature access with `hasEntitlement()` and `checkEntitlement()`
|
|
16
|
+
- **Heartbeat** – Automatic periodic heartbeats to report device activity
|
|
17
|
+
- **Telemetry** – Auto-collected device and environment data sent with each API request
|
|
16
18
|
- **Local caching** – Secure localStorage-based caching with clock tamper detection
|
|
17
19
|
- **Auto-retry with exponential backoff** – Resilient network handling
|
|
18
20
|
- **Event-driven architecture** – Subscribe to SDK lifecycle events
|
|
@@ -138,6 +140,14 @@ const sdk = new LicenseSeat({
|
|
|
138
140
|
autoValidateInterval: 3600000, // 1 hour (in ms)
|
|
139
141
|
autoInitialize: true, // Auto-validate cached license on init
|
|
140
142
|
|
|
143
|
+
// Heartbeat
|
|
144
|
+
heartbeatInterval: 300000, // 5 minutes (in ms), 0 to disable
|
|
145
|
+
|
|
146
|
+
// Telemetry
|
|
147
|
+
telemetryEnabled: true, // Set false to disable (e.g. GDPR)
|
|
148
|
+
appVersion: '1.2.0', // Your app version (sent in telemetry)
|
|
149
|
+
appBuild: '42', // Your app build number (sent in telemetry)
|
|
150
|
+
|
|
141
151
|
// Offline Support
|
|
142
152
|
offlineFallbackEnabled: false, // Enable offline validation fallback
|
|
143
153
|
maxOfflineDays: 0, // Max days offline (0 = disabled)
|
|
@@ -164,6 +174,10 @@ const sdk = new LicenseSeat({
|
|
|
164
174
|
| `storagePrefix` | `string` | `'licenseseat_'` | Prefix for localStorage keys |
|
|
165
175
|
| `autoValidateInterval` | `number` | `3600000` | Auto-validation interval in ms (1 hour) |
|
|
166
176
|
| `autoInitialize` | `boolean` | `true` | Auto-initialize and validate cached license |
|
|
177
|
+
| `heartbeatInterval` | `number` | `300000` | Heartbeat interval in ms (5 minutes). Set `0` to disable |
|
|
178
|
+
| `telemetryEnabled` | `boolean` | `true` | Enable telemetry collection. Set `false` for GDPR compliance |
|
|
179
|
+
| `appVersion` | `string` | `null` | Your app version string (sent as `app_version` in telemetry) |
|
|
180
|
+
| `appBuild` | `string` | `null` | Your app build identifier (sent as `app_build` in telemetry) |
|
|
167
181
|
| `offlineFallbackEnabled` | `boolean` | `false` | Enable offline validation on network errors |
|
|
168
182
|
| `maxOfflineDays` | `number` | `0` | Maximum days license works offline (0 = disabled) |
|
|
169
183
|
| `maxRetries` | `number` | `3` | Max retry attempts for failed API calls |
|
|
@@ -325,6 +339,23 @@ try {
|
|
|
325
339
|
|
|
326
340
|
> **Note:** This method tests API connectivity, not API key validity. A successful response means the API is reachable. Authentication errors will surface when calling protected endpoints like `activate()` or `validateLicense()`.
|
|
327
341
|
|
|
342
|
+
#### `sdk.heartbeat()`
|
|
343
|
+
|
|
344
|
+
Send a heartbeat to report that the current device is still active. Heartbeats are sent automatically at the configured `heartbeatInterval`, but you can also send one manually.
|
|
345
|
+
|
|
346
|
+
```javascript
|
|
347
|
+
try {
|
|
348
|
+
const result = await sdk.heartbeat();
|
|
349
|
+
console.log('Heartbeat received at:', result.received_at);
|
|
350
|
+
} catch (error) {
|
|
351
|
+
console.error('Heartbeat failed:', error);
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
Returns `undefined` if no active license is cached. When auto-heartbeat is enabled (the default), the SDK sends heartbeats every 5 minutes while a license is active. Auto-heartbeat starts automatically after `activate()` or when the SDK initializes with a cached license.
|
|
356
|
+
|
|
357
|
+
To disable auto-heartbeat, set `heartbeatInterval: 0` in the configuration.
|
|
358
|
+
|
|
328
359
|
#### `sdk.reset()`
|
|
329
360
|
|
|
330
361
|
Clear all cached data and reset SDK state.
|
|
@@ -403,6 +434,9 @@ sdk.off('activation:success', handler);
|
|
|
403
434
|
| **Auto-Validation** | | |
|
|
404
435
|
| `autovalidation:cycle` | Auto-validation scheduled | `{ nextRunAt: Date }` |
|
|
405
436
|
| `autovalidation:stopped` | Auto-validation stopped | – |
|
|
437
|
+
| **Heartbeat** | | |
|
|
438
|
+
| `heartbeat:success` | Heartbeat acknowledged by server | `HeartbeatResponse` |
|
|
439
|
+
| `heartbeat:cycle` | Auto-heartbeat tick completed | `{ nextRunAt: Date }` |
|
|
406
440
|
| **Network** | | |
|
|
407
441
|
| `network:online` | Network connectivity restored | – |
|
|
408
442
|
| `network:offline` | Network connectivity lost | `{ error }` |
|
|
@@ -568,6 +602,126 @@ console.log('Signature valid:', isValid);
|
|
|
568
602
|
|
|
569
603
|
---
|
|
570
604
|
|
|
605
|
+
## Telemetry
|
|
606
|
+
|
|
607
|
+
The SDK automatically collects non-PII (non-personally-identifiable) device and environment data and includes it with every POST request sent to the LicenseSeat API. This data helps you understand what platforms and environments your customers use.
|
|
608
|
+
|
|
609
|
+
Telemetry is **enabled by default** and can be disabled at any time.
|
|
610
|
+
|
|
611
|
+
### Collected Fields
|
|
612
|
+
|
|
613
|
+
| Field | Type | Example | Description |
|
|
614
|
+
| -------------------- | -------- | ---------------------- | ------------------------------------------------ |
|
|
615
|
+
| `sdk_name` | `string` | `"js"` | Always `"js"` for this SDK |
|
|
616
|
+
| `sdk_version` | `string` | `"0.4.0"` | SDK version |
|
|
617
|
+
| `os_name` | `string` | `"macOS"` | Operating system name |
|
|
618
|
+
| `os_version` | `string` | `"14.2.1"` | Operating system version |
|
|
619
|
+
| `platform` | `string` | `"browser"` | Runtime platform (`browser`, `node`, `electron`, `react-native`, `deno`, `bun`) |
|
|
620
|
+
| `device_model` | `string` | `null` | Device model (Chromium userAgentData only) |
|
|
621
|
+
| `device_type` | `string` | `"desktop"` | Device type (`desktop`, `phone`, `tablet`, `server`) |
|
|
622
|
+
| `locale` | `string` | `"en-US"` | Full locale string |
|
|
623
|
+
| `timezone` | `string` | `"America/New_York"` | IANA timezone |
|
|
624
|
+
| `language` | `string` | `"en"` | 2-letter language code |
|
|
625
|
+
| `architecture` | `string` | `"arm64"` | CPU architecture |
|
|
626
|
+
| `cpu_cores` | `number` | `10` | Number of logical CPU cores |
|
|
627
|
+
| `memory_gb` | `number` | `16` | Approximate RAM in GB (Chrome/Node.js only) |
|
|
628
|
+
| `screen_resolution` | `string` | `"1920x1080"` | Screen resolution |
|
|
629
|
+
| `display_scale` | `number` | `2` | Device pixel ratio |
|
|
630
|
+
| `browser_name` | `string` | `"Chrome"` | Browser name (browser environments only) |
|
|
631
|
+
| `browser_version` | `string` | `"123.0"` | Browser version (browser environments only) |
|
|
632
|
+
| `runtime_version` | `string` | `"20.11.0"` | Runtime version (Node.js, Deno, Bun, Electron) |
|
|
633
|
+
| `app_version` | `string` | `"1.2.0"` | Your app version (from `appVersion` config) |
|
|
634
|
+
| `app_build` | `string` | `"42"` | Your app build (from `appBuild` config) |
|
|
635
|
+
|
|
636
|
+
Fields that cannot be detected in the current environment are omitted (not sent as `null`).
|
|
637
|
+
|
|
638
|
+
### Providing App Version
|
|
639
|
+
|
|
640
|
+
Pass your own app version and build number via configuration so they appear in telemetry:
|
|
641
|
+
|
|
642
|
+
```javascript
|
|
643
|
+
const sdk = new LicenseSeat({
|
|
644
|
+
apiKey: 'your-key',
|
|
645
|
+
productSlug: 'your-product',
|
|
646
|
+
appVersion: '1.2.0',
|
|
647
|
+
appBuild: '42'
|
|
648
|
+
});
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
### Disabling Telemetry
|
|
652
|
+
|
|
653
|
+
To disable telemetry collection entirely (for example, to comply with GDPR or other privacy regulations):
|
|
654
|
+
|
|
655
|
+
```javascript
|
|
656
|
+
const sdk = new LicenseSeat({
|
|
657
|
+
apiKey: 'your-key',
|
|
658
|
+
productSlug: 'your-product',
|
|
659
|
+
telemetryEnabled: false
|
|
660
|
+
});
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
When telemetry is disabled, no device or environment data is attached to API requests.
|
|
664
|
+
|
|
665
|
+
### Privacy
|
|
666
|
+
|
|
667
|
+
Telemetry collects only non-personally-identifiable information. No IP addresses, user names, email addresses, or other PII are collected by the SDK. The data is used solely to help you understand the platforms and environments where your software is used.
|
|
668
|
+
|
|
669
|
+
Telemetry is opt-out: set `telemetryEnabled: false` to disable it completely.
|
|
670
|
+
|
|
671
|
+
---
|
|
672
|
+
|
|
673
|
+
## Heartbeat
|
|
674
|
+
|
|
675
|
+
The SDK sends periodic heartbeat signals to let the server know a device is still actively using the license. This enables usage analytics and helps detect inactive seats.
|
|
676
|
+
|
|
677
|
+
### How It Works
|
|
678
|
+
|
|
679
|
+
- After a license is activated (or when the SDK initializes with a cached license), a heartbeat timer starts automatically.
|
|
680
|
+
- The default interval is **5 minutes** (`300000` ms), configurable via `heartbeatInterval`.
|
|
681
|
+
- Each heartbeat sends the current `device_id` to the server.
|
|
682
|
+
- Heartbeats also run alongside auto-validation cycles.
|
|
683
|
+
|
|
684
|
+
### Manual Heartbeat
|
|
685
|
+
|
|
686
|
+
You can send a heartbeat at any time:
|
|
687
|
+
|
|
688
|
+
```javascript
|
|
689
|
+
await sdk.heartbeat();
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
### Configuring the Interval
|
|
693
|
+
|
|
694
|
+
```javascript
|
|
695
|
+
const sdk = new LicenseSeat({
|
|
696
|
+
apiKey: 'your-key',
|
|
697
|
+
productSlug: 'your-product',
|
|
698
|
+
heartbeatInterval: 600000 // 10 minutes
|
|
699
|
+
});
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
Set `heartbeatInterval: 0` to disable auto-heartbeat entirely. You can still call `sdk.heartbeat()` manually.
|
|
703
|
+
|
|
704
|
+
### Heartbeat Events
|
|
705
|
+
|
|
706
|
+
| Event | Description | Data |
|
|
707
|
+
| -------------------- | ---------------------------------- | ----------------------- |
|
|
708
|
+
| `heartbeat:success` | Heartbeat acknowledged by server | `HeartbeatResponse` |
|
|
709
|
+
| `heartbeat:cycle` | Auto-heartbeat tick completed | `{ nextRunAt: Date }` |
|
|
710
|
+
|
|
711
|
+
```javascript
|
|
712
|
+
sdk.on('heartbeat:success', (data) => {
|
|
713
|
+
console.log('Heartbeat received at:', data.received_at);
|
|
714
|
+
});
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
### Heartbeat Lifecycle
|
|
718
|
+
|
|
719
|
+
- **Starts** automatically after `sdk.activate()` succeeds, or on SDK init if a cached license exists.
|
|
720
|
+
- **Stops** automatically when `sdk.deactivate()`, `sdk.reset()`, or `sdk.destroy()` is called.
|
|
721
|
+
- Heartbeat failures are logged (in debug mode) but do not throw or interrupt the SDK.
|
|
722
|
+
|
|
723
|
+
---
|
|
724
|
+
|
|
571
725
|
## Error Handling
|
|
572
726
|
|
|
573
727
|
The SDK exports custom error classes for precise error handling:
|
|
@@ -833,6 +987,7 @@ licenseseat-js/
|
|
|
833
987
|
├── src/
|
|
834
988
|
│ ├── index.js # Entry point, exports
|
|
835
989
|
│ ├── LicenseSeat.js # Main SDK class
|
|
990
|
+
│ ├── telemetry.js # Telemetry collection (device/environment data)
|
|
836
991
|
│ ├── cache.js # LicenseCache (localStorage)
|
|
837
992
|
│ ├── errors.js # Error classes
|
|
838
993
|
│ ├── types.js # JSDoc type definitions
|
|
@@ -936,7 +1091,7 @@ Once published to npm, the package is automatically available on CDNs:
|
|
|
936
1091
|
**Version pinning** (recommended for production):
|
|
937
1092
|
```html
|
|
938
1093
|
<script type="module">
|
|
939
|
-
import LicenseSeat from 'https://esm.sh/@licenseseat/js@0.
|
|
1094
|
+
import LicenseSeat from 'https://esm.sh/@licenseseat/js@0.4.0';
|
|
940
1095
|
</script>
|
|
941
1096
|
```
|
|
942
1097
|
|