@grainql/analytics-web 1.7.4 → 2.1.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.
Files changed (258) hide show
  1. package/README.md +71 -718
  2. package/dist/activity.d.ts +59 -0
  3. package/dist/activity.d.ts.map +1 -0
  4. package/dist/cjs/activity.d.ts +59 -0
  5. package/dist/cjs/activity.d.ts.map +1 -0
  6. package/dist/cjs/activity.js +131 -0
  7. package/dist/cjs/activity.js.map +1 -0
  8. package/dist/cjs/consent.d.ts +68 -0
  9. package/dist/cjs/consent.d.ts.map +1 -0
  10. package/dist/cjs/consent.js +191 -0
  11. package/dist/cjs/consent.js.map +1 -0
  12. package/dist/cjs/cookies.d.ts +28 -0
  13. package/dist/cjs/cookies.d.ts.map +1 -0
  14. package/dist/cjs/cookies.js +95 -0
  15. package/dist/cjs/cookies.js.map +1 -0
  16. package/dist/cjs/heartbeat.d.ts +42 -0
  17. package/dist/cjs/heartbeat.d.ts.map +1 -0
  18. package/dist/cjs/heartbeat.js +92 -0
  19. package/dist/cjs/heartbeat.js.map +1 -0
  20. package/dist/cjs/index.d.ts +100 -3
  21. package/dist/cjs/index.d.ts.map +1 -1
  22. package/dist/cjs/index.js.map +1 -1
  23. package/dist/cjs/page-tracking.d.ts +60 -0
  24. package/dist/cjs/page-tracking.d.ts.map +1 -0
  25. package/dist/cjs/page-tracking.js +180 -0
  26. package/dist/cjs/page-tracking.js.map +1 -0
  27. package/dist/cjs/react/GrainProvider.d.ts +11 -0
  28. package/dist/cjs/react/GrainProvider.d.ts.map +1 -0
  29. package/dist/cjs/react/GrainProvider.js +79 -0
  30. package/dist/cjs/react/GrainProvider.js.map +1 -0
  31. package/dist/cjs/react/components/ConsentBanner.d.ts +16 -0
  32. package/dist/cjs/react/components/ConsentBanner.d.ts.map +1 -0
  33. package/dist/cjs/react/components/ConsentBanner.js +112 -0
  34. package/dist/cjs/react/components/ConsentBanner.js.map +1 -0
  35. package/dist/cjs/react/components/CookieNotice.d.ts +12 -0
  36. package/dist/cjs/react/components/CookieNotice.d.ts.map +1 -0
  37. package/dist/cjs/react/components/CookieNotice.js +62 -0
  38. package/dist/cjs/react/components/CookieNotice.js.map +1 -0
  39. package/dist/cjs/react/components/PrivacyPreferenceCenter.d.ts +12 -0
  40. package/dist/cjs/react/components/PrivacyPreferenceCenter.d.ts.map +1 -0
  41. package/dist/cjs/react/components/PrivacyPreferenceCenter.js +120 -0
  42. package/dist/cjs/react/components/PrivacyPreferenceCenter.js.map +1 -0
  43. package/dist/cjs/react/context.d.ts +11 -0
  44. package/dist/cjs/react/context.d.ts.map +1 -0
  45. package/dist/cjs/react/context.js +43 -0
  46. package/dist/cjs/react/context.js.map +1 -0
  47. package/dist/cjs/react/hooks/useAllConfigs.d.ts +8 -0
  48. package/dist/cjs/react/hooks/useAllConfigs.d.ts.map +1 -0
  49. package/dist/cjs/react/hooks/useAllConfigs.js +112 -0
  50. package/dist/cjs/react/hooks/useAllConfigs.js.map +1 -0
  51. package/dist/cjs/react/hooks/useConfig.d.ts +9 -0
  52. package/dist/cjs/react/hooks/useConfig.d.ts.map +1 -0
  53. package/dist/cjs/react/hooks/useConfig.js +116 -0
  54. package/dist/cjs/react/hooks/useConfig.js.map +1 -0
  55. package/dist/cjs/react/hooks/useConsent.d.ts +13 -0
  56. package/dist/cjs/react/hooks/useConsent.d.ts.map +1 -0
  57. package/dist/cjs/react/hooks/useConsent.js +84 -0
  58. package/dist/cjs/react/hooks/useConsent.js.map +1 -0
  59. package/dist/cjs/react/hooks/useDataDeletion.d.ts +17 -0
  60. package/dist/cjs/react/hooks/useDataDeletion.d.ts.map +1 -0
  61. package/dist/cjs/react/hooks/useDataDeletion.js +117 -0
  62. package/dist/cjs/react/hooks/useDataDeletion.js.map +1 -0
  63. package/dist/cjs/react/hooks/useGrainAnalytics.d.ts +6 -0
  64. package/dist/cjs/react/hooks/useGrainAnalytics.d.ts.map +1 -0
  65. package/dist/cjs/react/hooks/useGrainAnalytics.js +50 -0
  66. package/dist/cjs/react/hooks/useGrainAnalytics.js.map +1 -0
  67. package/dist/cjs/react/hooks/usePrivacyPreferences.d.ts +15 -0
  68. package/dist/cjs/react/hooks/usePrivacyPreferences.d.ts.map +1 -0
  69. package/dist/cjs/react/hooks/usePrivacyPreferences.js +82 -0
  70. package/dist/cjs/react/hooks/usePrivacyPreferences.js.map +1 -0
  71. package/dist/cjs/react/hooks/useTrack.d.ts +9 -0
  72. package/dist/cjs/react/hooks/useTrack.d.ts.map +1 -0
  73. package/dist/cjs/react/hooks/useTrack.js +53 -0
  74. package/dist/cjs/react/hooks/useTrack.js.map +1 -0
  75. package/dist/cjs/react/index.d.ts +47 -0
  76. package/dist/cjs/react/index.d.ts.map +1 -0
  77. package/dist/cjs/react/index.js +59 -0
  78. package/dist/cjs/react/index.js.map +1 -0
  79. package/dist/cjs/react/types.d.ts +33 -0
  80. package/dist/cjs/react/types.d.ts.map +1 -0
  81. package/dist/cjs/react/types.js +6 -0
  82. package/dist/cjs/react/types.js.map +1 -0
  83. package/dist/consent.d.ts +68 -0
  84. package/dist/consent.d.ts.map +1 -0
  85. package/dist/cookies.d.ts +28 -0
  86. package/dist/cookies.d.ts.map +1 -0
  87. package/dist/esm/activity.d.ts +59 -0
  88. package/dist/esm/activity.d.ts.map +1 -0
  89. package/dist/esm/activity.js +127 -0
  90. package/dist/esm/activity.js.map +1 -0
  91. package/dist/esm/consent.d.ts +68 -0
  92. package/dist/esm/consent.d.ts.map +1 -0
  93. package/dist/esm/consent.js +187 -0
  94. package/dist/esm/consent.js.map +1 -0
  95. package/dist/esm/cookies.d.ts +28 -0
  96. package/dist/esm/cookies.d.ts.map +1 -0
  97. package/dist/esm/cookies.js +89 -0
  98. package/dist/esm/cookies.js.map +1 -0
  99. package/dist/esm/heartbeat.d.ts +42 -0
  100. package/dist/esm/heartbeat.d.ts.map +1 -0
  101. package/dist/esm/heartbeat.js +88 -0
  102. package/dist/esm/heartbeat.js.map +1 -0
  103. package/dist/esm/index.d.ts +100 -3
  104. package/dist/esm/index.d.ts.map +1 -1
  105. package/dist/esm/index.js.map +1 -1
  106. package/dist/esm/page-tracking.d.ts +60 -0
  107. package/dist/esm/page-tracking.d.ts.map +1 -0
  108. package/dist/esm/page-tracking.js +176 -0
  109. package/dist/esm/page-tracking.js.map +1 -0
  110. package/dist/esm/react/GrainProvider.d.ts +11 -0
  111. package/dist/esm/react/GrainProvider.d.ts.map +1 -0
  112. package/dist/esm/react/GrainProvider.js +43 -0
  113. package/dist/esm/react/GrainProvider.js.map +1 -0
  114. package/dist/esm/react/components/ConsentBanner.d.ts +16 -0
  115. package/dist/esm/react/components/ConsentBanner.d.ts.map +1 -0
  116. package/dist/esm/react/components/ConsentBanner.js +76 -0
  117. package/dist/esm/react/components/ConsentBanner.js.map +1 -0
  118. package/dist/esm/react/components/CookieNotice.d.ts +12 -0
  119. package/dist/esm/react/components/CookieNotice.d.ts.map +1 -0
  120. package/dist/esm/react/components/CookieNotice.js +26 -0
  121. package/dist/esm/react/components/CookieNotice.js.map +1 -0
  122. package/dist/esm/react/components/PrivacyPreferenceCenter.d.ts +12 -0
  123. package/dist/esm/react/components/PrivacyPreferenceCenter.d.ts.map +1 -0
  124. package/dist/esm/react/components/PrivacyPreferenceCenter.js +84 -0
  125. package/dist/esm/react/components/PrivacyPreferenceCenter.js.map +1 -0
  126. package/dist/esm/react/context.d.ts +11 -0
  127. package/dist/esm/react/context.d.ts.map +1 -0
  128. package/dist/esm/react/context.js +7 -0
  129. package/dist/esm/react/context.js.map +1 -0
  130. package/dist/esm/react/hooks/useAllConfigs.d.ts +8 -0
  131. package/dist/esm/react/hooks/useAllConfigs.d.ts.map +1 -0
  132. package/dist/esm/react/hooks/useAllConfigs.js +76 -0
  133. package/dist/esm/react/hooks/useAllConfigs.js.map +1 -0
  134. package/dist/esm/react/hooks/useConfig.d.ts +9 -0
  135. package/dist/esm/react/hooks/useConfig.d.ts.map +1 -0
  136. package/dist/esm/react/hooks/useConfig.js +80 -0
  137. package/dist/esm/react/hooks/useConfig.js.map +1 -0
  138. package/dist/esm/react/hooks/useConsent.d.ts +13 -0
  139. package/dist/esm/react/hooks/useConsent.d.ts.map +1 -0
  140. package/dist/esm/react/hooks/useConsent.js +48 -0
  141. package/dist/esm/react/hooks/useConsent.js.map +1 -0
  142. package/dist/esm/react/hooks/useDataDeletion.d.ts +17 -0
  143. package/dist/esm/react/hooks/useDataDeletion.d.ts.map +1 -0
  144. package/dist/esm/react/hooks/useDataDeletion.js +81 -0
  145. package/dist/esm/react/hooks/useDataDeletion.js.map +1 -0
  146. package/dist/esm/react/hooks/useGrainAnalytics.d.ts +6 -0
  147. package/dist/esm/react/hooks/useGrainAnalytics.d.ts.map +1 -0
  148. package/dist/esm/react/hooks/useGrainAnalytics.js +14 -0
  149. package/dist/esm/react/hooks/useGrainAnalytics.js.map +1 -0
  150. package/dist/esm/react/hooks/usePrivacyPreferences.d.ts +15 -0
  151. package/dist/esm/react/hooks/usePrivacyPreferences.d.ts.map +1 -0
  152. package/dist/esm/react/hooks/usePrivacyPreferences.js +46 -0
  153. package/dist/esm/react/hooks/usePrivacyPreferences.js.map +1 -0
  154. package/dist/esm/react/hooks/useTrack.d.ts +9 -0
  155. package/dist/esm/react/hooks/useTrack.d.ts.map +1 -0
  156. package/dist/esm/react/hooks/useTrack.js +17 -0
  157. package/dist/esm/react/hooks/useTrack.js.map +1 -0
  158. package/dist/esm/react/index.d.ts +47 -0
  159. package/dist/esm/react/index.d.ts.map +1 -0
  160. package/dist/esm/react/index.js +45 -0
  161. package/dist/esm/react/index.js.map +1 -0
  162. package/dist/esm/react/types.d.ts +33 -0
  163. package/dist/esm/react/types.d.ts.map +1 -0
  164. package/dist/esm/react/types.js +5 -0
  165. package/dist/esm/react/types.js.map +1 -0
  166. package/dist/heartbeat.d.ts +42 -0
  167. package/dist/heartbeat.d.ts.map +1 -0
  168. package/dist/index.d.ts +100 -3
  169. package/dist/index.d.ts.map +1 -1
  170. package/dist/index.global.dev.js +903 -12
  171. package/dist/index.global.dev.js.map +3 -3
  172. package/dist/index.global.js +2 -2
  173. package/dist/index.global.js.map +4 -4
  174. package/dist/index.js +321 -11
  175. package/dist/index.mjs +321 -11
  176. package/dist/page-tracking.d.ts +60 -0
  177. package/dist/page-tracking.d.ts.map +1 -0
  178. package/dist/react/activity.d.ts +59 -0
  179. package/dist/react/activity.d.ts.map +1 -0
  180. package/dist/react/activity.js +130 -0
  181. package/dist/react/activity.mjs +126 -0
  182. package/dist/react/consent.d.ts +68 -0
  183. package/dist/react/consent.d.ts.map +1 -0
  184. package/dist/react/consent.js +190 -0
  185. package/dist/react/consent.mjs +186 -0
  186. package/dist/react/cookies.d.ts +28 -0
  187. package/dist/react/cookies.d.ts.map +1 -0
  188. package/dist/react/cookies.js +94 -0
  189. package/dist/react/cookies.mjs +88 -0
  190. package/dist/react/heartbeat.d.ts +42 -0
  191. package/dist/react/heartbeat.d.ts.map +1 -0
  192. package/dist/react/heartbeat.js +91 -0
  193. package/dist/react/heartbeat.mjs +87 -0
  194. package/dist/react/index.d.ts +502 -0
  195. package/dist/react/index.d.ts.map +1 -0
  196. package/dist/react/index.js +1491 -0
  197. package/dist/react/index.mjs +1486 -0
  198. package/dist/react/page-tracking.d.ts +60 -0
  199. package/dist/react/page-tracking.d.ts.map +1 -0
  200. package/dist/react/page-tracking.js +179 -0
  201. package/dist/react/page-tracking.mjs +175 -0
  202. package/dist/react/react/GrainProvider.d.ts +11 -0
  203. package/dist/react/react/GrainProvider.d.ts.map +1 -0
  204. package/dist/react/react/GrainProvider.js +45 -0
  205. package/dist/react/react/GrainProvider.mjs +42 -0
  206. package/dist/react/react/components/ConsentBanner.d.ts +16 -0
  207. package/dist/react/react/components/ConsentBanner.d.ts.map +1 -0
  208. package/dist/react/react/components/ConsentBanner.js +78 -0
  209. package/dist/react/react/components/ConsentBanner.mjs +75 -0
  210. package/dist/react/react/components/CookieNotice.d.ts +12 -0
  211. package/dist/react/react/components/CookieNotice.d.ts.map +1 -0
  212. package/dist/react/react/components/CookieNotice.js +28 -0
  213. package/dist/react/react/components/CookieNotice.mjs +25 -0
  214. package/dist/react/react/components/PrivacyPreferenceCenter.d.ts +12 -0
  215. package/dist/react/react/components/PrivacyPreferenceCenter.d.ts.map +1 -0
  216. package/dist/react/react/components/PrivacyPreferenceCenter.js +86 -0
  217. package/dist/react/react/components/PrivacyPreferenceCenter.mjs +83 -0
  218. package/dist/react/react/context.d.ts +11 -0
  219. package/dist/react/react/context.d.ts.map +1 -0
  220. package/dist/react/react/context.js +9 -0
  221. package/dist/react/react/context.mjs +6 -0
  222. package/dist/react/react/hooks/useAllConfigs.d.ts +8 -0
  223. package/dist/react/react/hooks/useAllConfigs.d.ts.map +1 -0
  224. package/dist/react/react/hooks/useAllConfigs.js +78 -0
  225. package/dist/react/react/hooks/useAllConfigs.mjs +75 -0
  226. package/dist/react/react/hooks/useConfig.d.ts +9 -0
  227. package/dist/react/react/hooks/useConfig.d.ts.map +1 -0
  228. package/dist/react/react/hooks/useConfig.js +82 -0
  229. package/dist/react/react/hooks/useConfig.mjs +79 -0
  230. package/dist/react/react/hooks/useConsent.d.ts +13 -0
  231. package/dist/react/react/hooks/useConsent.d.ts.map +1 -0
  232. package/dist/react/react/hooks/useConsent.js +50 -0
  233. package/dist/react/react/hooks/useConsent.mjs +47 -0
  234. package/dist/react/react/hooks/useDataDeletion.d.ts +17 -0
  235. package/dist/react/react/hooks/useDataDeletion.d.ts.map +1 -0
  236. package/dist/react/react/hooks/useDataDeletion.js +83 -0
  237. package/dist/react/react/hooks/useDataDeletion.mjs +80 -0
  238. package/dist/react/react/hooks/useGrainAnalytics.d.ts +6 -0
  239. package/dist/react/react/hooks/useGrainAnalytics.d.ts.map +1 -0
  240. package/dist/react/react/hooks/useGrainAnalytics.js +16 -0
  241. package/dist/react/react/hooks/useGrainAnalytics.mjs +13 -0
  242. package/dist/react/react/hooks/usePrivacyPreferences.d.ts +15 -0
  243. package/dist/react/react/hooks/usePrivacyPreferences.d.ts.map +1 -0
  244. package/dist/react/react/hooks/usePrivacyPreferences.js +48 -0
  245. package/dist/react/react/hooks/usePrivacyPreferences.mjs +45 -0
  246. package/dist/react/react/hooks/useTrack.d.ts +9 -0
  247. package/dist/react/react/hooks/useTrack.d.ts.map +1 -0
  248. package/dist/react/react/hooks/useTrack.js +19 -0
  249. package/dist/react/react/hooks/useTrack.mjs +16 -0
  250. package/dist/react/react/index.d.ts +47 -0
  251. package/dist/react/react/index.d.ts.map +1 -0
  252. package/dist/react/react/index.js +58 -0
  253. package/dist/react/react/index.mjs +44 -0
  254. package/dist/react/react/types.d.ts +33 -0
  255. package/dist/react/react/types.d.ts.map +1 -0
  256. package/dist/react/react/types.js +5 -0
  257. package/dist/react/react/types.mjs +4 -0
  258. package/package.json +20 -2
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Cookie utilities for Grain Analytics
3
+ * Provides GDPR-compliant cookie management with configurable options
4
+ */
5
+ export interface CookieConfig {
6
+ domain?: string;
7
+ path?: string;
8
+ sameSite?: 'strict' | 'lax' | 'none';
9
+ secure?: boolean;
10
+ maxAge?: number;
11
+ }
12
+ /**
13
+ * Set a cookie with configurable options
14
+ */
15
+ export declare function setCookie(name: string, value: string, config?: CookieConfig): void;
16
+ /**
17
+ * Get a cookie value by name
18
+ */
19
+ export declare function getCookie(name: string): string | null;
20
+ /**
21
+ * Delete a cookie by name
22
+ */
23
+ export declare function deleteCookie(name: string, config?: Pick<CookieConfig, 'domain' | 'path'>): void;
24
+ /**
25
+ * Check if cookies are available and working
26
+ */
27
+ export declare function areCookiesEnabled(): boolean;
28
+ //# sourceMappingURL=cookies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/cookies.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CA4BlF;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBrD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,MAAM,CAAC,GAAG,IAAI,CAmB/F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAY3C"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ /**
3
+ * Cookie utilities for Grain Analytics
4
+ * Provides GDPR-compliant cookie management with configurable options
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.setCookie = setCookie;
8
+ exports.getCookie = getCookie;
9
+ exports.deleteCookie = deleteCookie;
10
+ exports.areCookiesEnabled = areCookiesEnabled;
11
+ /**
12
+ * Set a cookie with configurable options
13
+ */
14
+ function setCookie(name, value, config) {
15
+ if (typeof document === 'undefined')
16
+ return;
17
+ const parts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];
18
+ if (config?.maxAge !== undefined) {
19
+ parts.push(`max-age=${config.maxAge}`);
20
+ }
21
+ if (config?.domain) {
22
+ parts.push(`domain=${config.domain}`);
23
+ }
24
+ if (config?.path) {
25
+ parts.push(`path=${config.path}`);
26
+ }
27
+ else {
28
+ parts.push('path=/');
29
+ }
30
+ if (config?.sameSite) {
31
+ parts.push(`samesite=${config.sameSite}`);
32
+ }
33
+ if (config?.secure) {
34
+ parts.push('secure');
35
+ }
36
+ document.cookie = parts.join('; ');
37
+ }
38
+ /**
39
+ * Get a cookie value by name
40
+ */
41
+ function getCookie(name) {
42
+ if (typeof document === 'undefined')
43
+ return null;
44
+ const nameEQ = encodeURIComponent(name) + '=';
45
+ const cookies = document.cookie.split(';');
46
+ for (let i = 0; i < cookies.length; i++) {
47
+ let cookie = cookies[i];
48
+ while (cookie.charAt(0) === ' ') {
49
+ cookie = cookie.substring(1);
50
+ }
51
+ if (cookie.indexOf(nameEQ) === 0) {
52
+ return decodeURIComponent(cookie.substring(nameEQ.length));
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+ /**
58
+ * Delete a cookie by name
59
+ */
60
+ function deleteCookie(name, config) {
61
+ if (typeof document === 'undefined')
62
+ return;
63
+ const parts = [
64
+ `${encodeURIComponent(name)}=`,
65
+ 'max-age=0',
66
+ ];
67
+ if (config?.domain) {
68
+ parts.push(`domain=${config.domain}`);
69
+ }
70
+ if (config?.path) {
71
+ parts.push(`path=${config.path}`);
72
+ }
73
+ else {
74
+ parts.push('path=/');
75
+ }
76
+ document.cookie = parts.join('; ');
77
+ }
78
+ /**
79
+ * Check if cookies are available and working
80
+ */
81
+ function areCookiesEnabled() {
82
+ if (typeof document === 'undefined')
83
+ return false;
84
+ try {
85
+ const testCookie = '_grain_cookie_test';
86
+ setCookie(testCookie, 'test', { maxAge: 1 });
87
+ const result = getCookie(testCookie) === 'test';
88
+ deleteCookie(testCookie);
89
+ return result;
90
+ }
91
+ catch {
92
+ return false;
93
+ }
94
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Cookie utilities for Grain Analytics
3
+ * Provides GDPR-compliant cookie management with configurable options
4
+ */
5
+ /**
6
+ * Set a cookie with configurable options
7
+ */
8
+ export function setCookie(name, value, config) {
9
+ if (typeof document === 'undefined')
10
+ return;
11
+ const parts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];
12
+ if (config?.maxAge !== undefined) {
13
+ parts.push(`max-age=${config.maxAge}`);
14
+ }
15
+ if (config?.domain) {
16
+ parts.push(`domain=${config.domain}`);
17
+ }
18
+ if (config?.path) {
19
+ parts.push(`path=${config.path}`);
20
+ }
21
+ else {
22
+ parts.push('path=/');
23
+ }
24
+ if (config?.sameSite) {
25
+ parts.push(`samesite=${config.sameSite}`);
26
+ }
27
+ if (config?.secure) {
28
+ parts.push('secure');
29
+ }
30
+ document.cookie = parts.join('; ');
31
+ }
32
+ /**
33
+ * Get a cookie value by name
34
+ */
35
+ export function getCookie(name) {
36
+ if (typeof document === 'undefined')
37
+ return null;
38
+ const nameEQ = encodeURIComponent(name) + '=';
39
+ const cookies = document.cookie.split(';');
40
+ for (let i = 0; i < cookies.length; i++) {
41
+ let cookie = cookies[i];
42
+ while (cookie.charAt(0) === ' ') {
43
+ cookie = cookie.substring(1);
44
+ }
45
+ if (cookie.indexOf(nameEQ) === 0) {
46
+ return decodeURIComponent(cookie.substring(nameEQ.length));
47
+ }
48
+ }
49
+ return null;
50
+ }
51
+ /**
52
+ * Delete a cookie by name
53
+ */
54
+ export function deleteCookie(name, config) {
55
+ if (typeof document === 'undefined')
56
+ return;
57
+ const parts = [
58
+ `${encodeURIComponent(name)}=`,
59
+ 'max-age=0',
60
+ ];
61
+ if (config?.domain) {
62
+ parts.push(`domain=${config.domain}`);
63
+ }
64
+ if (config?.path) {
65
+ parts.push(`path=${config.path}`);
66
+ }
67
+ else {
68
+ parts.push('path=/');
69
+ }
70
+ document.cookie = parts.join('; ');
71
+ }
72
+ /**
73
+ * Check if cookies are available and working
74
+ */
75
+ export function areCookiesEnabled() {
76
+ if (typeof document === 'undefined')
77
+ return false;
78
+ try {
79
+ const testCookie = '_grain_cookie_test';
80
+ setCookie(testCookie, 'test', { maxAge: 1 });
81
+ const result = getCookie(testCookie) === 'test';
82
+ deleteCookie(testCookie);
83
+ return result;
84
+ }
85
+ catch {
86
+ return false;
87
+ }
88
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Heartbeat Manager for Grain Analytics
3
+ * Tracks session activity with consent-aware behavior
4
+ */
5
+ import type { ActivityDetector } from './activity';
6
+ export interface HeartbeatConfig {
7
+ activeInterval: number;
8
+ inactiveInterval: number;
9
+ debug?: boolean;
10
+ }
11
+ export interface HeartbeatTracker {
12
+ trackSystemEvent(eventName: string, properties: Record<string, unknown>): void;
13
+ hasConsent(category?: string): boolean;
14
+ getEffectiveUserId(): string;
15
+ getEphemeralSessionId(): string;
16
+ getCurrentPage(): string | null;
17
+ getEventCountSinceLastHeartbeat(): number;
18
+ resetEventCountSinceLastHeartbeat(): void;
19
+ }
20
+ export declare class HeartbeatManager {
21
+ private config;
22
+ private tracker;
23
+ private activityDetector;
24
+ private heartbeatTimer;
25
+ private isDestroyed;
26
+ private lastHeartbeatTime;
27
+ private currentInterval;
28
+ constructor(tracker: HeartbeatTracker, activityDetector: ActivityDetector, config: HeartbeatConfig);
29
+ /**
30
+ * Schedule the next heartbeat based on current activity
31
+ */
32
+ private scheduleNextHeartbeat;
33
+ /**
34
+ * Send heartbeat event
35
+ */
36
+ private sendHeartbeat;
37
+ /**
38
+ * Destroy the heartbeat manager
39
+ */
40
+ destroy(): void;
41
+ }
42
+ //# sourceMappingURL=heartbeat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/heartbeat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/E,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,kBAAkB,IAAI,MAAM,CAAC;IAC7B,qBAAqB,IAAI,MAAM,CAAC;IAChC,cAAc,IAAI,MAAM,GAAG,IAAI,CAAC;IAChC,+BAA+B,IAAI,MAAM,CAAC;IAC1C,iCAAiC,IAAI,IAAI,CAAC;CAC3C;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,eAAe,CAAS;gBAG9B,OAAO,EAAE,gBAAgB,EACzB,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,EAAE,eAAe;IAYzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAyB7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAqCrB;;OAEG;IACH,OAAO,IAAI,IAAI;CAchB"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /**
3
+ * Heartbeat Manager for Grain Analytics
4
+ * Tracks session activity with consent-aware behavior
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.HeartbeatManager = void 0;
8
+ class HeartbeatManager {
9
+ constructor(tracker, activityDetector, config) {
10
+ this.heartbeatTimer = null;
11
+ this.isDestroyed = false;
12
+ this.tracker = tracker;
13
+ this.activityDetector = activityDetector;
14
+ this.config = config;
15
+ this.lastHeartbeatTime = Date.now();
16
+ this.currentInterval = config.activeInterval;
17
+ // Start heartbeat tracking
18
+ this.scheduleNextHeartbeat();
19
+ }
20
+ /**
21
+ * Schedule the next heartbeat based on current activity
22
+ */
23
+ scheduleNextHeartbeat() {
24
+ if (this.isDestroyed)
25
+ return;
26
+ // Clear existing timer
27
+ if (this.heartbeatTimer !== null) {
28
+ clearTimeout(this.heartbeatTimer);
29
+ }
30
+ // Determine interval based on activity
31
+ const isActive = this.activityDetector.isActive(60000); // 1 minute threshold
32
+ this.currentInterval = isActive ? this.config.activeInterval : this.config.inactiveInterval;
33
+ // Schedule next heartbeat
34
+ this.heartbeatTimer = window.setTimeout(() => {
35
+ this.sendHeartbeat();
36
+ this.scheduleNextHeartbeat();
37
+ }, this.currentInterval);
38
+ if (this.config.debug) {
39
+ console.log(`[Heartbeat] Scheduled next heartbeat in ${this.currentInterval / 1000}s (${isActive ? 'active' : 'inactive'})`);
40
+ }
41
+ }
42
+ /**
43
+ * Send heartbeat event
44
+ */
45
+ sendHeartbeat() {
46
+ if (this.isDestroyed)
47
+ return;
48
+ const now = Date.now();
49
+ const isActive = this.activityDetector.isActive(60000); // 1 minute threshold
50
+ const hasConsent = this.tracker.hasConsent('analytics');
51
+ // Base properties (always included)
52
+ const properties = {
53
+ type: 'heartbeat',
54
+ status: isActive ? 'active' : 'inactive',
55
+ timestamp: now,
56
+ };
57
+ // Enhanced properties when consent is granted
58
+ if (hasConsent) {
59
+ const page = this.tracker.getCurrentPage();
60
+ if (page) {
61
+ properties.page = page;
62
+ }
63
+ properties.duration = now - this.lastHeartbeatTime;
64
+ properties.event_count = this.tracker.getEventCountSinceLastHeartbeat();
65
+ // Reset event count
66
+ this.tracker.resetEventCountSinceLastHeartbeat();
67
+ }
68
+ // Track the heartbeat event
69
+ this.tracker.trackSystemEvent('_grain_heartbeat', properties);
70
+ this.lastHeartbeatTime = now;
71
+ if (this.config.debug) {
72
+ console.log('[Heartbeat] Sent heartbeat:', properties);
73
+ }
74
+ }
75
+ /**
76
+ * Destroy the heartbeat manager
77
+ */
78
+ destroy() {
79
+ if (this.isDestroyed)
80
+ return;
81
+ if (this.heartbeatTimer !== null) {
82
+ clearTimeout(this.heartbeatTimer);
83
+ this.heartbeatTimer = null;
84
+ }
85
+ this.isDestroyed = true;
86
+ if (this.config.debug) {
87
+ console.log('[Heartbeat] Destroyed');
88
+ }
89
+ }
90
+ }
91
+ exports.HeartbeatManager = HeartbeatManager;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Heartbeat Manager for Grain Analytics
3
+ * Tracks session activity with consent-aware behavior
4
+ */
5
+ export class HeartbeatManager {
6
+ constructor(tracker, activityDetector, config) {
7
+ this.heartbeatTimer = null;
8
+ this.isDestroyed = false;
9
+ this.tracker = tracker;
10
+ this.activityDetector = activityDetector;
11
+ this.config = config;
12
+ this.lastHeartbeatTime = Date.now();
13
+ this.currentInterval = config.activeInterval;
14
+ // Start heartbeat tracking
15
+ this.scheduleNextHeartbeat();
16
+ }
17
+ /**
18
+ * Schedule the next heartbeat based on current activity
19
+ */
20
+ scheduleNextHeartbeat() {
21
+ if (this.isDestroyed)
22
+ return;
23
+ // Clear existing timer
24
+ if (this.heartbeatTimer !== null) {
25
+ clearTimeout(this.heartbeatTimer);
26
+ }
27
+ // Determine interval based on activity
28
+ const isActive = this.activityDetector.isActive(60000); // 1 minute threshold
29
+ this.currentInterval = isActive ? this.config.activeInterval : this.config.inactiveInterval;
30
+ // Schedule next heartbeat
31
+ this.heartbeatTimer = window.setTimeout(() => {
32
+ this.sendHeartbeat();
33
+ this.scheduleNextHeartbeat();
34
+ }, this.currentInterval);
35
+ if (this.config.debug) {
36
+ console.log(`[Heartbeat] Scheduled next heartbeat in ${this.currentInterval / 1000}s (${isActive ? 'active' : 'inactive'})`);
37
+ }
38
+ }
39
+ /**
40
+ * Send heartbeat event
41
+ */
42
+ sendHeartbeat() {
43
+ if (this.isDestroyed)
44
+ return;
45
+ const now = Date.now();
46
+ const isActive = this.activityDetector.isActive(60000); // 1 minute threshold
47
+ const hasConsent = this.tracker.hasConsent('analytics');
48
+ // Base properties (always included)
49
+ const properties = {
50
+ type: 'heartbeat',
51
+ status: isActive ? 'active' : 'inactive',
52
+ timestamp: now,
53
+ };
54
+ // Enhanced properties when consent is granted
55
+ if (hasConsent) {
56
+ const page = this.tracker.getCurrentPage();
57
+ if (page) {
58
+ properties.page = page;
59
+ }
60
+ properties.duration = now - this.lastHeartbeatTime;
61
+ properties.event_count = this.tracker.getEventCountSinceLastHeartbeat();
62
+ // Reset event count
63
+ this.tracker.resetEventCountSinceLastHeartbeat();
64
+ }
65
+ // Track the heartbeat event
66
+ this.tracker.trackSystemEvent('_grain_heartbeat', properties);
67
+ this.lastHeartbeatTime = now;
68
+ if (this.config.debug) {
69
+ console.log('[Heartbeat] Sent heartbeat:', properties);
70
+ }
71
+ }
72
+ /**
73
+ * Destroy the heartbeat manager
74
+ */
75
+ destroy() {
76
+ if (this.isDestroyed)
77
+ return;
78
+ if (this.heartbeatTimer !== null) {
79
+ clearTimeout(this.heartbeatTimer);
80
+ this.heartbeatTimer = null;
81
+ }
82
+ this.isDestroyed = true;
83
+ if (this.config.debug) {
84
+ console.log('[Heartbeat] Destroyed');
85
+ }
86
+ }
87
+ }