@grainql/analytics-web 3.0.2 → 3.0.4
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 +4 -4
- package/dist/cjs/consent.d.ts +4 -4
- package/dist/cjs/consent.js +14 -14
- package/dist/cjs/consent.js.map +1 -1
- package/dist/cjs/id-manager.d.ts +1 -1
- package/dist/cjs/id-manager.js +1 -1
- package/dist/cjs/index.d.ts +3 -2
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/consent.d.ts +4 -4
- package/dist/consent.js +14 -14
- package/dist/esm/consent.d.ts +4 -4
- package/dist/esm/consent.js +14 -14
- package/dist/esm/consent.js.map +1 -1
- package/dist/esm/id-manager.d.ts +1 -1
- package/dist/esm/id-manager.js +1 -1
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/id-manager.d.ts +1 -1
- package/dist/id-manager.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.dev.js +27 -18
- package/dist/index.global.dev.js.map +2 -2
- package/dist/index.global.js +8 -8
- package/dist/index.global.js.map +3 -3
- package/dist/index.js +19 -6
- package/dist/index.mjs +19 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -98,7 +98,7 @@ class GrainAnalytics {
|
|
|
98
98
|
configRefreshInterval: 300000, // 5 minutes
|
|
99
99
|
enableConfigCache: true,
|
|
100
100
|
// Privacy defaults (v2.0)
|
|
101
|
-
consentMode: '
|
|
101
|
+
consentMode: 'COOKIELESS', // Default: privacy-first, no permanent tracking
|
|
102
102
|
waitForConsent: false,
|
|
103
103
|
disableAutoProperties: false,
|
|
104
104
|
// Automatic Tracking defaults
|
|
@@ -191,7 +191,7 @@ class GrainAnalytics {
|
|
|
191
191
|
*/
|
|
192
192
|
shouldAllowPersistentStorage() {
|
|
193
193
|
const hasConsent = this.consentManager.hasConsent('analytics');
|
|
194
|
-
const isCookieless = this.config.consentMode === '
|
|
194
|
+
const isCookieless = this.config.consentMode === 'COOKIELESS';
|
|
195
195
|
const userExplicitlyIdentified = !!this.globalUserId;
|
|
196
196
|
const isJWTAuth = this.config.authStrategy === 'JWT';
|
|
197
197
|
// Never allow persistent storage in cookieless mode
|
|
@@ -1085,7 +1085,7 @@ class GrainAnalytics {
|
|
|
1085
1085
|
this.log(`Event waiting for consent: ${event.eventName}`, event.properties);
|
|
1086
1086
|
return;
|
|
1087
1087
|
}
|
|
1088
|
-
// v2.0: GDPR Strict falls back to
|
|
1088
|
+
// v2.0: GDPR Strict falls back to cookieless mode (daily rotating IDs)
|
|
1089
1089
|
// Events are never blocked - IdManager already provides correct ID (daily or permanent)
|
|
1090
1090
|
const hasConsent = this.consentManager.hasConsent('analytics');
|
|
1091
1091
|
// Add tracking flags to indicate consent status
|
|
@@ -1557,10 +1557,23 @@ class GrainAnalytics {
|
|
|
1557
1557
|
const userId = options.userId || this.getEffectiveUserIdInternal();
|
|
1558
1558
|
const immediateKeys = options.immediateKeys || [];
|
|
1559
1559
|
const properties = options.properties || {};
|
|
1560
|
+
// Include currentUrl from options, or automatically get it from window.location if available
|
|
1561
|
+
// Strip query parameters and hash to match backend normalization
|
|
1562
|
+
let currentUrl = options.currentUrl ?? (typeof window !== 'undefined' ? window.location.href : undefined);
|
|
1563
|
+
if (currentUrl) {
|
|
1564
|
+
try {
|
|
1565
|
+
const urlObj = new URL(currentUrl);
|
|
1566
|
+
currentUrl = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`;
|
|
1567
|
+
}
|
|
1568
|
+
catch {
|
|
1569
|
+
// If URL parsing fails, use as-is
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1560
1572
|
const request = {
|
|
1561
1573
|
userId,
|
|
1562
1574
|
immediateKeys,
|
|
1563
1575
|
properties,
|
|
1576
|
+
currentUrl,
|
|
1564
1577
|
};
|
|
1565
1578
|
let lastError;
|
|
1566
1579
|
for (let attempt = 0; attempt <= this.config.retryAttempts; attempt++) {
|
|
@@ -1782,7 +1795,7 @@ class GrainAnalytics {
|
|
|
1782
1795
|
// Privacy & Consent Methods
|
|
1783
1796
|
/**
|
|
1784
1797
|
* Grant consent for tracking (v2.0)
|
|
1785
|
-
* Switches from
|
|
1798
|
+
* Switches from cookieless mode to permanent IDs
|
|
1786
1799
|
* @param categories - Optional array of consent categories (e.g., ['analytics', 'functional'])
|
|
1787
1800
|
*/
|
|
1788
1801
|
grantConsent(categories) {
|
|
@@ -1807,7 +1820,7 @@ class GrainAnalytics {
|
|
|
1807
1820
|
}
|
|
1808
1821
|
/**
|
|
1809
1822
|
* Revoke consent for tracking (v2.0)
|
|
1810
|
-
* Switches from permanent IDs to
|
|
1823
|
+
* Switches from permanent IDs to cookieless mode
|
|
1811
1824
|
* @param categories - Optional array of categories to revoke (if not provided, revokes all)
|
|
1812
1825
|
*/
|
|
1813
1826
|
revokeConsent(categories) {
|
|
@@ -1816,7 +1829,7 @@ class GrainAnalytics {
|
|
|
1816
1829
|
// Sync ID manager with consent state
|
|
1817
1830
|
const idMode = this.consentManager.getIdMode();
|
|
1818
1831
|
this.idManager.setMode(idMode);
|
|
1819
|
-
this.log('Consent revoked, switched to
|
|
1832
|
+
this.log('Consent revoked, switched to cookieless mode', categories);
|
|
1820
1833
|
// Clear queued events when consent is fully revoked
|
|
1821
1834
|
if (!this.consentManager.hasConsent()) {
|
|
1822
1835
|
this.eventQueue = [];
|
package/dist/index.mjs
CHANGED
|
@@ -57,7 +57,7 @@ export class GrainAnalytics {
|
|
|
57
57
|
configRefreshInterval: 300000, // 5 minutes
|
|
58
58
|
enableConfigCache: true,
|
|
59
59
|
// Privacy defaults (v2.0)
|
|
60
|
-
consentMode: '
|
|
60
|
+
consentMode: 'COOKIELESS', // Default: privacy-first, no permanent tracking
|
|
61
61
|
waitForConsent: false,
|
|
62
62
|
disableAutoProperties: false,
|
|
63
63
|
// Automatic Tracking defaults
|
|
@@ -150,7 +150,7 @@ export class GrainAnalytics {
|
|
|
150
150
|
*/
|
|
151
151
|
shouldAllowPersistentStorage() {
|
|
152
152
|
const hasConsent = this.consentManager.hasConsent('analytics');
|
|
153
|
-
const isCookieless = this.config.consentMode === '
|
|
153
|
+
const isCookieless = this.config.consentMode === 'COOKIELESS';
|
|
154
154
|
const userExplicitlyIdentified = !!this.globalUserId;
|
|
155
155
|
const isJWTAuth = this.config.authStrategy === 'JWT';
|
|
156
156
|
// Never allow persistent storage in cookieless mode
|
|
@@ -1044,7 +1044,7 @@ export class GrainAnalytics {
|
|
|
1044
1044
|
this.log(`Event waiting for consent: ${event.eventName}`, event.properties);
|
|
1045
1045
|
return;
|
|
1046
1046
|
}
|
|
1047
|
-
// v2.0: GDPR Strict falls back to
|
|
1047
|
+
// v2.0: GDPR Strict falls back to cookieless mode (daily rotating IDs)
|
|
1048
1048
|
// Events are never blocked - IdManager already provides correct ID (daily or permanent)
|
|
1049
1049
|
const hasConsent = this.consentManager.hasConsent('analytics');
|
|
1050
1050
|
// Add tracking flags to indicate consent status
|
|
@@ -1516,10 +1516,23 @@ export class GrainAnalytics {
|
|
|
1516
1516
|
const userId = options.userId || this.getEffectiveUserIdInternal();
|
|
1517
1517
|
const immediateKeys = options.immediateKeys || [];
|
|
1518
1518
|
const properties = options.properties || {};
|
|
1519
|
+
// Include currentUrl from options, or automatically get it from window.location if available
|
|
1520
|
+
// Strip query parameters and hash to match backend normalization
|
|
1521
|
+
let currentUrl = options.currentUrl ?? (typeof window !== 'undefined' ? window.location.href : undefined);
|
|
1522
|
+
if (currentUrl) {
|
|
1523
|
+
try {
|
|
1524
|
+
const urlObj = new URL(currentUrl);
|
|
1525
|
+
currentUrl = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`;
|
|
1526
|
+
}
|
|
1527
|
+
catch {
|
|
1528
|
+
// If URL parsing fails, use as-is
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1519
1531
|
const request = {
|
|
1520
1532
|
userId,
|
|
1521
1533
|
immediateKeys,
|
|
1522
1534
|
properties,
|
|
1535
|
+
currentUrl,
|
|
1523
1536
|
};
|
|
1524
1537
|
let lastError;
|
|
1525
1538
|
for (let attempt = 0; attempt <= this.config.retryAttempts; attempt++) {
|
|
@@ -1741,7 +1754,7 @@ export class GrainAnalytics {
|
|
|
1741
1754
|
// Privacy & Consent Methods
|
|
1742
1755
|
/**
|
|
1743
1756
|
* Grant consent for tracking (v2.0)
|
|
1744
|
-
* Switches from
|
|
1757
|
+
* Switches from cookieless mode to permanent IDs
|
|
1745
1758
|
* @param categories - Optional array of consent categories (e.g., ['analytics', 'functional'])
|
|
1746
1759
|
*/
|
|
1747
1760
|
grantConsent(categories) {
|
|
@@ -1766,7 +1779,7 @@ export class GrainAnalytics {
|
|
|
1766
1779
|
}
|
|
1767
1780
|
/**
|
|
1768
1781
|
* Revoke consent for tracking (v2.0)
|
|
1769
|
-
* Switches from permanent IDs to
|
|
1782
|
+
* Switches from permanent IDs to cookieless mode
|
|
1770
1783
|
* @param categories - Optional array of categories to revoke (if not provided, revokes all)
|
|
1771
1784
|
*/
|
|
1772
1785
|
revokeConsent(categories) {
|
|
@@ -1775,7 +1788,7 @@ export class GrainAnalytics {
|
|
|
1775
1788
|
// Sync ID manager with consent state
|
|
1776
1789
|
const idMode = this.consentManager.getIdMode();
|
|
1777
1790
|
this.idManager.setMode(idMode);
|
|
1778
|
-
this.log('Consent revoked, switched to
|
|
1791
|
+
this.log('Consent revoked, switched to cookieless mode', categories);
|
|
1779
1792
|
// Clear queued events when consent is fully revoked
|
|
1780
1793
|
if (!this.consentManager.hasConsent()) {
|
|
1781
1794
|
this.eventQueue = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grainql/analytics-web",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.4",
|
|
4
4
|
"description": "Lightweight TypeScript SDK for sending analytics events and managing remote configurations via Grain's REST API",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|