@refraction-ui/react 0.19.1 → 0.20.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 (342) hide show
  1. package/dist/chunk-533MCMSU.js +2355 -0
  2. package/dist/chunk-533MCMSU.js.map +7 -0
  3. package/dist/chunk-AMK4VCBG.js +250 -0
  4. package/dist/chunk-AMK4VCBG.js.map +7 -0
  5. package/dist/chunk-BOLFYVI6.js +90 -0
  6. package/dist/chunk-BOLFYVI6.js.map +7 -0
  7. package/dist/chunk-F7B64KT3.js +187 -0
  8. package/dist/chunk-F7B64KT3.js.map +7 -0
  9. package/dist/chunk-FD37DFCC.js +77 -0
  10. package/dist/chunk-FD37DFCC.js.map +7 -0
  11. package/dist/chunk-H54FLNAF.js +132 -0
  12. package/dist/chunk-H54FLNAF.js.map +7 -0
  13. package/dist/chunk-INP46354.js +664 -0
  14. package/dist/chunk-INP46354.js.map +7 -0
  15. package/dist/chunk-ONACRMG4.js +116 -0
  16. package/dist/chunk-ONACRMG4.js.map +7 -0
  17. package/dist/chunk-SDZ3LROZ.js +7 -0
  18. package/dist/chunk-SDZ3LROZ.js.map +7 -0
  19. package/dist/chunk-TOZBR4GL.js +154 -0
  20. package/dist/chunk-TOZBR4GL.js.map +7 -0
  21. package/dist/chunk-UNEM2TRI.js +225 -0
  22. package/dist/chunk-UNEM2TRI.js.map +7 -0
  23. package/dist/chunk-VK3EQ34F.js +92 -0
  24. package/dist/chunk-VK3EQ34F.js.map +7 -0
  25. package/dist/chunk-WK2IIUFO.js +316 -0
  26. package/dist/chunk-WK2IIUFO.js.map +7 -0
  27. package/dist/chunk-WSPJTQAV.js +59 -0
  28. package/dist/chunk-WSPJTQAV.js.map +7 -0
  29. package/dist/chunk-XWP763SH.js +3 -2
  30. package/dist/chunk-XWP763SH.js.map +7 -1
  31. package/dist/chunk-Y2FNNAIL.js +80 -0
  32. package/dist/chunk-Y2FNNAIL.js.map +1 -0
  33. package/dist/{chunk-4A4BW3GR.js → chunk-ZF3OHCGV.js} +28 -5
  34. package/dist/chunk-ZF3OHCGV.js.map +7 -0
  35. package/dist/form.cjs +5 -11
  36. package/dist/form.cjs.map +1 -1
  37. package/dist/form.js +6 -12
  38. package/dist/form.js.map +1 -1
  39. package/dist/index.cjs +2879 -33936
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +1 -0
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.js +126 -28780
  44. package/dist/internal/react-app-shell/index.d.cts +2 -22
  45. package/dist/internal/react-app-shell/index.d.ts +2 -22
  46. package/dist/internal/react-badge/index.d.cts +5 -0
  47. package/dist/internal/react-badge/index.d.ts +5 -0
  48. package/dist/internal/react-callout/index.d.cts +4 -0
  49. package/dist/internal/react-callout/index.d.ts +4 -0
  50. package/dist/internal/react-card/index.d.cts +8 -1
  51. package/dist/internal/react-card/index.d.ts +8 -1
  52. package/dist/internal/react-collapsible/index.d.cts +0 -3
  53. package/dist/internal/react-collapsible/index.d.ts +0 -3
  54. package/dist/internal/react-combobox/index.d.cts +0 -3
  55. package/dist/internal/react-combobox/index.d.ts +0 -3
  56. package/dist/internal/react-command/index.d.cts +0 -3
  57. package/dist/internal/react-command/index.d.ts +0 -3
  58. package/dist/internal/react-data-table/index.d.cts +0 -3
  59. package/dist/internal/react-data-table/index.d.ts +0 -3
  60. package/dist/internal/react-dialog/index.d.cts +0 -3
  61. package/dist/internal/react-dialog/index.d.ts +0 -3
  62. package/dist/internal/react-dropdown-menu/index.d.cts +0 -3
  63. package/dist/internal/react-dropdown-menu/index.d.ts +0 -3
  64. package/dist/internal/react-feedback-dialog/index.d.cts +0 -3
  65. package/dist/internal/react-feedback-dialog/index.d.ts +0 -3
  66. package/dist/internal/react-form/index.d.cts +2 -21
  67. package/dist/internal/react-form/index.d.ts +2 -21
  68. package/dist/internal/react-keyboard-shortcut/index.d.cts +0 -6
  69. package/dist/internal/react-keyboard-shortcut/index.d.ts +0 -6
  70. package/dist/internal/react-link-card/index.d.cts +8 -2
  71. package/dist/internal/react-link-card/index.d.ts +8 -2
  72. package/dist/internal/react-popover/index.d.cts +0 -3
  73. package/dist/internal/react-popover/index.d.ts +0 -3
  74. package/dist/internal/react-sheet/index.d.cts +0 -3
  75. package/dist/internal/react-sheet/index.d.ts +0 -3
  76. package/dist/internal/react-slot/index.d.cts +23 -0
  77. package/dist/internal/react-slot/index.d.ts +23 -0
  78. package/dist/internal/react-toast/index.d.cts +0 -3
  79. package/dist/internal/react-toast/index.d.ts +0 -3
  80. package/dist/internal/react-tooltip/index.d.cts +0 -3
  81. package/dist/internal/react-tooltip/index.d.ts +0 -3
  82. package/dist/react-accordion.js +125 -0
  83. package/dist/react-accordion.js.map +7 -0
  84. package/dist/react-ai.js +257 -0
  85. package/dist/react-ai.js.map +7 -0
  86. package/dist/react-analytics.js +1698 -0
  87. package/dist/react-analytics.js.map +7 -0
  88. package/dist/react-animated-text.js +164 -0
  89. package/dist/react-animated-text.js.map +7 -0
  90. package/dist/react-app-shell.js +631 -0
  91. package/dist/react-app-shell.js.map +7 -0
  92. package/dist/react-audience-feature-card.js +53 -0
  93. package/dist/react-audience-feature-card.js.map +7 -0
  94. package/dist/react-audio-room.js +166 -0
  95. package/dist/react-audio-room.js.map +7 -0
  96. package/dist/react-auth.js +211 -0
  97. package/dist/react-auth.js.map +7 -0
  98. package/dist/react-avatar-group.js +154 -0
  99. package/dist/react-avatar-group.js.map +7 -0
  100. package/dist/react-avatar.js +168 -0
  101. package/dist/react-avatar.js.map +7 -0
  102. package/dist/react-badge.js +86 -0
  103. package/dist/react-badge.js.map +7 -0
  104. package/dist/react-bottom-nav.js +67 -0
  105. package/dist/react-bottom-nav.js.map +7 -0
  106. package/dist/react-brand-network-cell.js +92 -0
  107. package/dist/react-brand-network-cell.js.map +7 -0
  108. package/dist/react-breadcrumbs.js +104 -0
  109. package/dist/react-breadcrumbs.js.map +7 -0
  110. package/dist/react-browser-chrome-mock.js +89 -0
  111. package/dist/react-browser-chrome-mock.js.map +7 -0
  112. package/dist/react-button.js +13 -0
  113. package/dist/react-button.js.map +7 -0
  114. package/dist/react-calendar.js +301 -0
  115. package/dist/react-calendar.js.map +7 -0
  116. package/dist/react-call-controls.js +113 -0
  117. package/dist/react-call-controls.js.map +7 -0
  118. package/dist/react-callout.js +152 -0
  119. package/dist/react-callout.js.map +7 -0
  120. package/dist/react-card-grid.js +34 -0
  121. package/dist/react-card-grid.js.map +7 -0
  122. package/dist/react-card.js +200 -0
  123. package/dist/react-card.js.map +7 -0
  124. package/dist/react-carousel.js +132 -0
  125. package/dist/react-carousel.js.map +7 -0
  126. package/dist/react-charts.js +509 -0
  127. package/dist/react-charts.js.map +7 -0
  128. package/dist/react-checkbox.js +156 -0
  129. package/dist/react-checkbox.js.map +7 -0
  130. package/dist/react-checklist.js +168 -0
  131. package/dist/react-checklist.js.map +7 -0
  132. package/dist/react-code-block.js +78 -0
  133. package/dist/react-code-block.js.map +7 -0
  134. package/dist/react-code-editor.js +184 -0
  135. package/dist/react-code-editor.js.map +7 -0
  136. package/dist/react-collapsible.js +192 -0
  137. package/dist/react-collapsible.js.map +7 -0
  138. package/dist/react-combobox.js +609 -0
  139. package/dist/react-combobox.js.map +7 -0
  140. package/dist/react-command-input.js +202 -0
  141. package/dist/react-command-input.js.map +7 -0
  142. package/dist/react-command.js +364 -0
  143. package/dist/react-command.js.map +7 -0
  144. package/dist/react-composer.js +2036 -0
  145. package/dist/react-composer.js.map +7 -0
  146. package/dist/react-content-protection.js +133 -0
  147. package/dist/react-content-protection.js.map +7 -0
  148. package/dist/react-conversation.js +1226 -0
  149. package/dist/react-conversation.js.map +7 -0
  150. package/dist/react-cookie-consent.js +291 -0
  151. package/dist/react-cookie-consent.js.map +7 -0
  152. package/dist/react-data-table.js +310 -0
  153. package/dist/react-data-table.js.map +7 -0
  154. package/dist/react-date-picker.js +95 -0
  155. package/dist/react-date-picker.js.map +7 -0
  156. package/dist/react-device-frame.js +137 -0
  157. package/dist/react-device-frame.js.map +7 -0
  158. package/dist/react-dialog.js +218 -0
  159. package/dist/react-dialog.js.map +7 -0
  160. package/dist/react-diff-viewer.js +460 -0
  161. package/dist/react-diff-viewer.js.map +7 -0
  162. package/dist/react-dropdown-menu.js +292 -0
  163. package/dist/react-dropdown-menu.js.map +7 -0
  164. package/dist/react-editor-status-bar.js +148 -0
  165. package/dist/react-editor-status-bar.js.map +7 -0
  166. package/dist/react-editor-tabs.js +159 -0
  167. package/dist/react-editor-tabs.js.map +7 -0
  168. package/dist/react-emoji-picker.js +238 -0
  169. package/dist/react-emoji-picker.js.map +7 -0
  170. package/dist/react-empty-state.js +90 -0
  171. package/dist/react-empty-state.js.map +7 -0
  172. package/dist/react-feedback-dialog.js +275 -0
  173. package/dist/react-feedback-dialog.js.map +7 -0
  174. package/dist/react-file-tree.js +376 -0
  175. package/dist/react-file-tree.js.map +7 -0
  176. package/dist/react-file-upload.js +360 -0
  177. package/dist/react-file-upload.js.map +7 -0
  178. package/dist/react-floating-reactions.js +124 -0
  179. package/dist/react-floating-reactions.js.map +7 -0
  180. package/dist/react-flow-editor.js +198 -0
  181. package/dist/react-flow-editor.js.map +7 -0
  182. package/dist/react-footer.js +67 -0
  183. package/dist/react-footer.js.map +7 -0
  184. package/dist/react-graph-view.js +197 -0
  185. package/dist/react-graph-view.js.map +7 -0
  186. package/dist/react-icon-system.js +9 -0
  187. package/dist/react-icon-system.js.map +7 -0
  188. package/dist/react-infinite-canvas.js +8 -0
  189. package/dist/react-infinite-canvas.js.map +7 -0
  190. package/dist/react-inline-editor.js +216 -0
  191. package/dist/react-inline-editor.js.map +7 -0
  192. package/dist/react-input-group.js +150 -0
  193. package/dist/react-input-group.js.map +7 -0
  194. package/dist/react-input.js +10 -0
  195. package/dist/react-input.js.map +7 -0
  196. package/dist/react-install-prompt.js +132 -0
  197. package/dist/react-install-prompt.js.map +7 -0
  198. package/dist/react-kanban-board.js +198 -0
  199. package/dist/react-kanban-board.js.map +7 -0
  200. package/dist/react-keyboard-shortcut.js +36 -0
  201. package/dist/react-keyboard-shortcut.js.map +7 -0
  202. package/dist/react-language-selector.js +311 -0
  203. package/dist/react-language-selector.js.map +7 -0
  204. package/dist/react-link-card.js +48 -0
  205. package/dist/react-link-card.js.map +7 -0
  206. package/dist/react-live-captions.js +92 -0
  207. package/dist/react-live-captions.js.map +7 -0
  208. package/dist/react-live-cursors.js +145 -0
  209. package/dist/react-live-cursors.js.map +7 -0
  210. package/dist/react-live-transcript.js +117 -0
  211. package/dist/react-live-transcript.js.map +7 -0
  212. package/dist/react-location-selector.js +252 -0
  213. package/dist/react-location-selector.js.map +7 -0
  214. package/dist/react-logger.js +415 -0
  215. package/dist/react-logger.js.map +7 -0
  216. package/dist/react-markdown-renderer.js +12 -0
  217. package/dist/react-markdown-renderer.js.map +7 -0
  218. package/dist/react-marquee-strip.js +62 -0
  219. package/dist/react-marquee-strip.js.map +7 -0
  220. package/dist/react-mascot.js +367 -0
  221. package/dist/react-mascot.js.map +7 -0
  222. package/dist/react-mastery-bar.js +97 -0
  223. package/dist/react-mastery-bar.js.map +7 -0
  224. package/dist/react-mini-map.js +207 -0
  225. package/dist/react-mini-map.js.map +7 -0
  226. package/dist/react-mobile-nav.js +216 -0
  227. package/dist/react-mobile-nav.js.map +7 -0
  228. package/dist/react-navbar.js +96 -0
  229. package/dist/react-navbar.js.map +7 -0
  230. package/dist/react-numbered-steps.js +67 -0
  231. package/dist/react-numbered-steps.js.map +7 -0
  232. package/dist/react-otp-input.js +318 -0
  233. package/dist/react-otp-input.js.map +7 -0
  234. package/dist/react-pagination.js +199 -0
  235. package/dist/react-pagination.js.map +7 -0
  236. package/dist/react-password-input.js +104 -0
  237. package/dist/react-password-input.js.map +7 -0
  238. package/dist/react-payment.js +81 -0
  239. package/dist/react-payment.js.map +7 -0
  240. package/dist/react-popover.js +176 -0
  241. package/dist/react-popover.js.map +7 -0
  242. package/dist/react-pre-call-lobby.js +309 -0
  243. package/dist/react-pre-call-lobby.js.map +7 -0
  244. package/dist/react-presence-indicator.js +86 -0
  245. package/dist/react-presence-indicator.js.map +7 -0
  246. package/dist/react-pricing-card.js +142 -0
  247. package/dist/react-pricing-card.js.map +7 -0
  248. package/dist/react-progress-display.js +188 -0
  249. package/dist/react-progress-display.js.map +7 -0
  250. package/dist/react-radial-gauge.js +193 -0
  251. package/dist/react-radial-gauge.js.map +7 -0
  252. package/dist/react-radio.js +169 -0
  253. package/dist/react-radio.js.map +7 -0
  254. package/dist/react-rating-scale.js +171 -0
  255. package/dist/react-rating-scale.js.map +7 -0
  256. package/dist/react-reaction-bar.js +111 -0
  257. package/dist/react-reaction-bar.js.map +7 -0
  258. package/dist/react-resizable-layout.js +298 -0
  259. package/dist/react-resizable-layout.js.map +7 -0
  260. package/dist/react-rich-editor.js +1 -0
  261. package/dist/react-rich-editor.js.map +7 -0
  262. package/dist/react-search-bar.js +285 -0
  263. package/dist/react-search-bar.js.map +7 -0
  264. package/dist/react-section-head.js +65 -0
  265. package/dist/react-section-head.js.map +7 -0
  266. package/dist/react-segmented-control.js +215 -0
  267. package/dist/react-segmented-control.js.map +7 -0
  268. package/dist/react-select.js +389 -0
  269. package/dist/react-select.js.map +7 -0
  270. package/dist/react-separator.js +86 -0
  271. package/dist/react-separator.js.map +7 -0
  272. package/dist/react-sheet.js +310 -0
  273. package/dist/react-sheet.js.map +7 -0
  274. package/dist/react-sidebar.js +100 -0
  275. package/dist/react-sidebar.js.map +7 -0
  276. package/dist/react-skeleton.js +91 -0
  277. package/dist/react-skeleton.js.map +7 -0
  278. package/dist/react-skip-to-content.js +38 -0
  279. package/dist/react-skip-to-content.js.map +7 -0
  280. package/dist/react-slide-viewer.js +264 -0
  281. package/dist/react-slide-viewer.js.map +7 -0
  282. package/dist/react-slider.js +105 -0
  283. package/dist/react-slider.js.map +7 -0
  284. package/dist/react-slot-picker.js +184 -0
  285. package/dist/react-slot-picker.js.map +7 -0
  286. package/dist/react-slot.js +7 -0
  287. package/dist/react-slot.js.map +7 -0
  288. package/dist/react-social-auth-button.js +169 -0
  289. package/dist/react-social-auth-button.js.map +7 -0
  290. package/dist/react-sortable-list.js +204 -0
  291. package/dist/react-sortable-list.js.map +7 -0
  292. package/dist/react-stat-grid.js +69 -0
  293. package/dist/react-stat-grid.js.map +7 -0
  294. package/dist/react-status-indicator.js +117 -0
  295. package/dist/react-status-indicator.js.map +7 -0
  296. package/dist/react-steps.js +167 -0
  297. package/dist/react-steps.js.map +7 -0
  298. package/dist/react-sticky-note.js +131 -0
  299. package/dist/react-sticky-note.js.map +7 -0
  300. package/dist/react-switch.js +139 -0
  301. package/dist/react-switch.js.map +7 -0
  302. package/dist/react-table-of-contents.js +80 -0
  303. package/dist/react-table-of-contents.js.map +7 -0
  304. package/dist/react-tabs.js +230 -0
  305. package/dist/react-tabs.js.map +7 -0
  306. package/dist/react-terminal.js +101 -0
  307. package/dist/react-terminal.js.map +7 -0
  308. package/dist/react-test-results.js +158 -0
  309. package/dist/react-test-results.js.map +7 -0
  310. package/dist/react-textarea.js +89 -0
  311. package/dist/react-textarea.js.map +7 -0
  312. package/dist/react-thread-view.js +139 -0
  313. package/dist/react-thread-view.js.map +7 -0
  314. package/dist/react-timeline.js +153 -0
  315. package/dist/react-timeline.js.map +7 -0
  316. package/dist/react-toast.js +253 -0
  317. package/dist/react-toast.js.map +7 -0
  318. package/dist/react-tooltip.js +221 -0
  319. package/dist/react-tooltip.js.map +7 -0
  320. package/dist/react-version-selector.js +270 -0
  321. package/dist/react-version-selector.js.map +7 -0
  322. package/dist/react-video-grid.js +129 -0
  323. package/dist/react-video-grid.js.map +7 -0
  324. package/dist/react-video-player.js +206 -0
  325. package/dist/react-video-player.js.map +7 -0
  326. package/dist/react-video-tile.js +8 -0
  327. package/dist/react-video-tile.js.map +7 -0
  328. package/dist/react-voice-pill.js +314 -0
  329. package/dist/react-voice-pill.js.map +7 -0
  330. package/dist/react-waveform.js +558 -0
  331. package/dist/react-waveform.js.map +7 -0
  332. package/dist/react-wizard.js +337 -0
  333. package/dist/react-wizard.js.map +7 -0
  334. package/dist/styles.css +7 -0
  335. package/dist/theme.js +1 -1
  336. package/package.json +3 -2
  337. package/dist/applicationinsights-web-H7OBLIVJ.js +0 -23393
  338. package/dist/applicationinsights-web-H7OBLIVJ.js.map +0 -1
  339. package/dist/chunk-4A4BW3GR.js.map +0 -1
  340. package/dist/index.js.map +0 -1
  341. package/dist/module-X3HTTRQK.js +0 -6438
  342. package/dist/module-X3HTTRQK.js.map +0 -1
@@ -0,0 +1,1698 @@
1
+ import {
2
+ devWarn
3
+ } from "./chunk-ZF3OHCGV.js";
4
+
5
+ // ../react-analytics/dist/index.js
6
+ import * as React from "react";
7
+
8
+ // ../analytics/dist/index.js
9
+ var SCHEMA_VERSION = 1;
10
+ function uuidv4() {
11
+ const c = typeof globalThis !== "undefined" ? globalThis.crypto : void 0;
12
+ if (c && typeof c.randomUUID === "function") {
13
+ return c.randomUUID();
14
+ }
15
+ const bytes = new Uint8Array(16);
16
+ if (c && typeof c.getRandomValues === "function") {
17
+ c.getRandomValues(bytes);
18
+ } else {
19
+ for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256);
20
+ }
21
+ bytes[6] = bytes[6] & 15 | 64;
22
+ bytes[8] = bytes[8] & 63 | 128;
23
+ const hex = [];
24
+ for (let i = 0; i < 256; i++) hex.push((i + 256).toString(16).slice(1));
25
+ return hex[bytes[0]] + hex[bytes[1]] + hex[bytes[2]] + hex[bytes[3]] + "-" + hex[bytes[4]] + hex[bytes[5]] + "-" + hex[bytes[6]] + hex[bytes[7]] + "-" + hex[bytes[8]] + hex[bytes[9]] + "-" + hex[bytes[10]] + hex[bytes[11]] + hex[bytes[12]] + hex[bytes[13]] + hex[bytes[14]] + hex[bytes[15]];
26
+ }
27
+ var UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
28
+ function isUuidV4(value) {
29
+ return typeof value === "string" && UUID_V4_RE.test(value);
30
+ }
31
+ function createMemoryStorage() {
32
+ const map = /* @__PURE__ */ new Map();
33
+ return {
34
+ get: (k) => map.has(k) ? map.get(k) : null,
35
+ set: (k, v) => {
36
+ map.set(k, v);
37
+ },
38
+ remove: (k) => {
39
+ map.delete(k);
40
+ }
41
+ };
42
+ }
43
+ function createLocalStorageAdapter(ls) {
44
+ return {
45
+ get: (k) => {
46
+ try {
47
+ return ls.getItem(k);
48
+ } catch {
49
+ return null;
50
+ }
51
+ },
52
+ set: (k, v) => {
53
+ try {
54
+ ls.setItem(k, v);
55
+ } catch {
56
+ }
57
+ },
58
+ remove: (k) => {
59
+ try {
60
+ ls.removeItem(k);
61
+ } catch {
62
+ }
63
+ }
64
+ };
65
+ }
66
+ function createCookieAdapter(doc, maxAgeSeconds = 60 * 60 * 24 * 365) {
67
+ const read = (k) => {
68
+ const target = encodeURIComponent(k) + "=";
69
+ const parts = doc.cookie ? doc.cookie.split(";") : [];
70
+ for (const part of parts) {
71
+ const c = part.trim();
72
+ if (c.startsWith(target)) {
73
+ return decodeURIComponent(c.slice(target.length));
74
+ }
75
+ }
76
+ return null;
77
+ };
78
+ return {
79
+ get: read,
80
+ set: (k, v) => {
81
+ doc.cookie = `${encodeURIComponent(k)}=${encodeURIComponent(
82
+ v
83
+ )}; path=/; max-age=${maxAgeSeconds}; SameSite=Lax`;
84
+ },
85
+ remove: (k) => {
86
+ doc.cookie = `${encodeURIComponent(k)}=; path=/; max-age=0; SameSite=Lax`;
87
+ }
88
+ };
89
+ }
90
+ function resolveStorage(override) {
91
+ if (override) return override;
92
+ const g = globalThis;
93
+ if (g.localStorage) {
94
+ try {
95
+ const probe = "__rfx_a_probe__";
96
+ g.localStorage.setItem(probe, "1");
97
+ g.localStorage.removeItem(probe);
98
+ return createLocalStorageAdapter(g.localStorage);
99
+ } catch {
100
+ }
101
+ }
102
+ if (g.document && typeof g.document.cookie === "string") {
103
+ return createCookieAdapter(g.document);
104
+ }
105
+ return createMemoryStorage();
106
+ }
107
+ var DEFAULT_SESSION_TIMEOUT_MS = 30 * 60 * 1e3;
108
+ var DEFAULT_KEY = "rfx:analytics:session";
109
+ var CAMPAIGN_PARAMS = [
110
+ "utm_source",
111
+ "utm_medium",
112
+ "utm_campaign",
113
+ "utm_term",
114
+ "utm_content",
115
+ "gclid",
116
+ "fbclid",
117
+ "msclkid"
118
+ ];
119
+ function campaignFingerprint(search) {
120
+ if (!search) return void 0;
121
+ let qs = search;
122
+ const q = qs.indexOf("?");
123
+ if (q !== -1) qs = qs.slice(q + 1);
124
+ let params;
125
+ try {
126
+ params = new URLSearchParams(qs);
127
+ } catch {
128
+ return void 0;
129
+ }
130
+ const pairs = [];
131
+ for (const p of CAMPAIGN_PARAMS) {
132
+ const v = params.get(p);
133
+ if (v) pairs.push(`${p}=${v}`);
134
+ }
135
+ return pairs.length ? pairs.join("&") : void 0;
136
+ }
137
+ function createSession(config, now = () => Date.now()) {
138
+ const storage = resolveStorage(config?.storage);
139
+ const key = config?.storageKey ?? DEFAULT_KEY;
140
+ const timeoutMs = config?.timeoutMs ?? DEFAULT_SESSION_TIMEOUT_MS;
141
+ const resetOnCampaign = config?.resetOnCampaign ?? true;
142
+ function read() {
143
+ const raw = storage.get(key);
144
+ if (!raw) return null;
145
+ try {
146
+ const parsed = JSON.parse(raw);
147
+ if (parsed && typeof parsed.id === "string") return parsed;
148
+ } catch {
149
+ }
150
+ return null;
151
+ }
152
+ function write(s) {
153
+ storage.set(key, JSON.stringify(s));
154
+ }
155
+ function mint(campaign) {
156
+ const s = {
157
+ id: uuidv4(),
158
+ lastActivity: now(),
159
+ campaign
160
+ };
161
+ write(s);
162
+ return s;
163
+ }
164
+ function ensure(campaign) {
165
+ const existing = read();
166
+ const t = now();
167
+ if (!existing) return mint(campaign);
168
+ if (t - existing.lastActivity > timeoutMs) {
169
+ return mint(campaign);
170
+ }
171
+ if (resetOnCampaign && campaign !== void 0 && existing.campaign !== campaign) {
172
+ return mint(campaign);
173
+ }
174
+ return existing;
175
+ }
176
+ return {
177
+ /** Get the current session id, rotating if expired. */
178
+ id(campaign) {
179
+ return ensure(campaign).id;
180
+ },
181
+ /** Force a brand-new session. */
182
+ start(campaign) {
183
+ return mint(campaign).id;
184
+ },
185
+ /** End the current session (next id() mints a fresh one). */
186
+ end() {
187
+ storage.remove(key);
188
+ },
189
+ /** Touch activity so the inactivity window slides forward. */
190
+ touch(campaign) {
191
+ const s = ensure(campaign);
192
+ s.lastActivity = now();
193
+ write(s);
194
+ return s.id;
195
+ },
196
+ /** Attach/merge session-scoped properties. */
197
+ set(props) {
198
+ const s = ensure();
199
+ s.props = { ...s.props ?? {}, ...props };
200
+ write(s);
201
+ },
202
+ /** Read session-scoped properties (undefined when none). */
203
+ props() {
204
+ return read()?.props;
205
+ }
206
+ };
207
+ }
208
+ var DEFAULT_KEY2 = "rfx:analytics:anon";
209
+ function createIdentity(config) {
210
+ const storage = resolveStorage(config?.storage);
211
+ const key = config?.storageKey ?? DEFAULT_KEY2;
212
+ let userId;
213
+ function loadOrMintAnon() {
214
+ const existing = storage.get(key);
215
+ if (isUuidV4(existing)) return existing;
216
+ const fresh = uuidv4();
217
+ storage.set(key, fresh);
218
+ return fresh;
219
+ }
220
+ let anonymousId = loadOrMintAnon();
221
+ return {
222
+ anonymousId() {
223
+ return anonymousId;
224
+ },
225
+ userId() {
226
+ return userId;
227
+ },
228
+ /** identify(): bind an opaque app user id (no validation, no persistence). */
229
+ setUserId(id) {
230
+ userId = id;
231
+ },
232
+ /**
233
+ * alias(): returns the stitch pair for the envelope. `previousId`
234
+ * defaults to the current user or anonymous id.
235
+ */
236
+ alias(nextUserId, previousId) {
237
+ const prev = previousId ?? userId ?? anonymousId;
238
+ userId = nextUserId;
239
+ return { userId: nextUserId, previousId: prev };
240
+ },
241
+ /**
242
+ * reset(): privacy-safe logout. Drops the user binding and mints a brand
243
+ * new anonymousId so the next visitor is not stitched to the old one.
244
+ */
245
+ reset() {
246
+ userId = void 0;
247
+ anonymousId = uuidv4();
248
+ storage.set(key, anonymousId);
249
+ return anonymousId;
250
+ }
251
+ };
252
+ }
253
+ function createConsent(config) {
254
+ const granted = new Set(config?.granted ?? []);
255
+ return {
256
+ strict: config?.strict ?? false,
257
+ grant(...categories) {
258
+ for (const c of categories) granted.add(c);
259
+ },
260
+ revoke(...categories) {
261
+ for (const c of categories) granted.delete(c);
262
+ },
263
+ granted() {
264
+ return [...granted];
265
+ },
266
+ isGranted(category) {
267
+ return granted.has(category);
268
+ },
269
+ allows(required) {
270
+ if (!required || required.length === 0) return true;
271
+ return required.every((c) => granted.has(c));
272
+ }
273
+ };
274
+ }
275
+ var PII_DENY_LIST = [
276
+ "email",
277
+ "phone",
278
+ "mobile",
279
+ "firstname",
280
+ "lastname",
281
+ "fullname",
282
+ "givenname",
283
+ "surname",
284
+ "password",
285
+ "passwd",
286
+ "ssn",
287
+ "creditcard",
288
+ "cardnumber",
289
+ "cvv",
290
+ "dob",
291
+ "dateofbirth",
292
+ "address"
293
+ ];
294
+ var PII_EXACT_KEYS = ["name"];
295
+ var REDACTED = "[REDACTED]";
296
+ function normalize(key) {
297
+ return key.toLowerCase().replace(/[_\-\s]/g, "");
298
+ }
299
+ function createRedactor(extraKeys = []) {
300
+ const exact = /* @__PURE__ */ new Set([
301
+ ...extraKeys.map(normalize),
302
+ ...PII_EXACT_KEYS.map(normalize)
303
+ ]);
304
+ const deny = PII_DENY_LIST.map(normalize);
305
+ const shouldRedact = (key) => {
306
+ const n = normalize(key);
307
+ if (exact.has(n)) return true;
308
+ return deny.some((d) => n.includes(d));
309
+ };
310
+ const walk = (value) => {
311
+ if (Array.isArray(value)) return value.map(walk);
312
+ if (value && typeof value === "object") {
313
+ const out = {};
314
+ for (const [k, v] of Object.entries(value)) {
315
+ out[k] = shouldRedact(k) ? REDACTED : walk(v);
316
+ }
317
+ return out;
318
+ }
319
+ return value;
320
+ };
321
+ return {
322
+ shouldRedact,
323
+ /** Redact a properties/traits bag (returns a new object). */
324
+ redact(props) {
325
+ if (!props) return props;
326
+ return walk(props);
327
+ }
328
+ };
329
+ }
330
+ var NO_RETRY = /* @__PURE__ */ new Set([400, 401, 413]);
331
+ function base64(input) {
332
+ const g = globalThis;
333
+ if (typeof g.btoa === "function") {
334
+ return g.btoa(input);
335
+ }
336
+ if (g.Buffer) {
337
+ return g.Buffer.from(input, "utf-8").toString("base64");
338
+ }
339
+ throw new Error("No base64 implementation available (btoa/Buffer)");
340
+ }
341
+ function byteLength(s) {
342
+ const g = globalThis;
343
+ if (g.TextEncoder) return new g.TextEncoder().encode(s).length;
344
+ return unescape(encodeURIComponent(s)).length;
345
+ }
346
+ var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
347
+ function splitBatch(batch, maxBatchBytes, maxEventBytes) {
348
+ const batches = [];
349
+ const dropped = [];
350
+ let current = [];
351
+ let currentBytes = 2;
352
+ for (const ev of batch) {
353
+ const evBytes = byteLength(JSON.stringify(ev));
354
+ if (evBytes > maxEventBytes) {
355
+ dropped.push(ev);
356
+ continue;
357
+ }
358
+ if (current.length && currentBytes + evBytes + 1 > maxBatchBytes) {
359
+ batches.push(current);
360
+ current = [];
361
+ currentBytes = 2;
362
+ }
363
+ current.push(ev);
364
+ currentBytes += evBytes + 1;
365
+ }
366
+ if (current.length) batches.push(current);
367
+ return { batches, dropped };
368
+ }
369
+ function createHttpSink(options) {
370
+ const {
371
+ endpoint,
372
+ writeKey,
373
+ maxRetries = 3,
374
+ backoffBaseMs = 500,
375
+ consentCategories = ["analytics"],
376
+ maxBatchBytes = 5e5,
377
+ maxEventBytes = 32e3
378
+ } = options;
379
+ const base = endpoint.replace(/\/+$/, "");
380
+ const url = `${base}/v${SCHEMA_VERSION}/batch`;
381
+ const authHeader = `Basic ${base64(`${writeKey}:`)}`;
382
+ const now = options.now ?? (() => /* @__PURE__ */ new Date());
383
+ const resolveFetch2 = () => {
384
+ if (options.fetchImpl) return options.fetchImpl;
385
+ const f = globalThis.fetch;
386
+ if (!f) throw new Error("No fetch implementation available");
387
+ return f;
388
+ };
389
+ const resolveBeacon = () => {
390
+ if (options.beaconImpl) return options.beaconImpl;
391
+ const nav = globalThis.navigator;
392
+ if (nav && typeof nav.sendBeacon === "function") {
393
+ return (u, body) => nav.sendBeacon(u, body);
394
+ }
395
+ return void 0;
396
+ };
397
+ function envelope(batch) {
398
+ return {
399
+ batch,
400
+ sentAt: now().toISOString(),
401
+ batchId: uuidv4()
402
+ };
403
+ }
404
+ function sendViaBeacon(batch) {
405
+ const beacon = resolveBeacon();
406
+ if (!beacon) return false;
407
+ const beaconUrl = `${url}?writeKey=${encodeURIComponent(writeKey)}`;
408
+ return beacon(beaconUrl, JSON.stringify(envelope(batch)));
409
+ }
410
+ async function sendViaFetch(batch) {
411
+ const doFetch = resolveFetch2();
412
+ const body = JSON.stringify(envelope(batch));
413
+ for (let attempt = 0; ; attempt++) {
414
+ let status;
415
+ try {
416
+ const res = await doFetch(url, {
417
+ method: "POST",
418
+ headers: {
419
+ "Content-Type": "application/json",
420
+ Authorization: authHeader
421
+ },
422
+ body,
423
+ keepalive: true
424
+ });
425
+ status = res.status;
426
+ } catch {
427
+ status = 0;
428
+ }
429
+ if (status >= 200 && status < 300) return;
430
+ if (NO_RETRY.has(status)) return;
431
+ if (attempt >= maxRetries) return;
432
+ const delay = backoffBaseMs * 2 ** attempt;
433
+ await sleep(delay);
434
+ }
435
+ }
436
+ return {
437
+ name: "http",
438
+ consentCategories,
439
+ async deliver(batch, ctx) {
440
+ if (batch.length === 0) return;
441
+ const { batches } = splitBatch(
442
+ batch,
443
+ maxBatchBytes,
444
+ maxEventBytes
445
+ );
446
+ for (const part of batches) {
447
+ if (ctx.unload) {
448
+ if (sendViaBeacon(part)) continue;
449
+ void sendViaFetch(part);
450
+ } else {
451
+ await sendViaFetch(part);
452
+ }
453
+ }
454
+ }
455
+ };
456
+ }
457
+ function createConsoleSink(options = {}) {
458
+ const logger = options.logger ?? globalThis.console;
459
+ return {
460
+ name: "console",
461
+ consentCategories: options.consentCategories,
462
+ deliver(batch) {
463
+ for (const ev of batch) {
464
+ const label = `[analytics] ${ev.type}${ev.event ? ` ${ev.event}` : ""}`;
465
+ if (typeof logger.groupCollapsed === "function") {
466
+ logger.groupCollapsed(label);
467
+ logger.log(ev);
468
+ logger.groupEnd?.();
469
+ } else {
470
+ logger.log(label, ev);
471
+ }
472
+ }
473
+ }
474
+ };
475
+ }
476
+ function createNoopAnalytics() {
477
+ const sessionId = "00000000-0000-4000-8000-000000000000";
478
+ const noop = () => {
479
+ };
480
+ const api = {
481
+ track: noop,
482
+ identify: noop,
483
+ page: noop,
484
+ screen: noop,
485
+ group: noop,
486
+ alias: noop,
487
+ session: {
488
+ id: () => sessionId,
489
+ start: () => sessionId,
490
+ end: noop,
491
+ set: noop
492
+ },
493
+ consent: {
494
+ grant: noop,
495
+ revoke: noop,
496
+ granted: () => [],
497
+ isGranted: () => false
498
+ },
499
+ anonymousId: () => sessionId,
500
+ userId: () => void 0,
501
+ with: () => api,
502
+ addSink: noop,
503
+ removeSink: noop,
504
+ get sinks() {
505
+ return [];
506
+ },
507
+ flush: async () => {
508
+ },
509
+ reset: noop,
510
+ enabled: false
511
+ };
512
+ return api;
513
+ }
514
+ var LIBRARY = {
515
+ name: "@refraction-ui/analytics",
516
+ version: "0.1.0"
517
+ };
518
+ function readPage() {
519
+ const g = globalThis;
520
+ if (!g.location && !g.document) return void 0;
521
+ return {
522
+ path: g.location?.pathname,
523
+ url: g.location?.href,
524
+ search: g.location?.search,
525
+ title: g.document?.title,
526
+ referrer: g.document?.referrer
527
+ };
528
+ }
529
+ function createAnalytics(config) {
530
+ if (config.enabled === false) {
531
+ return createNoopAnalytics();
532
+ }
533
+ const { app, env } = config;
534
+ const preset = config.preset ?? (env === "production" ? "prod" : "dev");
535
+ const sampleRate = config.sampleRate ?? 1;
536
+ const batchSize = config.batchSize ?? 20;
537
+ const flushIntervalMs = config.flushIntervalMs ?? 1e4;
538
+ const now = config.now ?? (() => /* @__PURE__ */ new Date());
539
+ const random = config.random ?? (() => Math.random());
540
+ const session = createSession(config.session);
541
+ const identity = createIdentity(config.identity);
542
+ const consent = createConsent(config.consent);
543
+ const redactor = createRedactor(config.redactKeys);
544
+ const sinks = /* @__PURE__ */ new Map();
545
+ const sinkOrder = [];
546
+ const initialized = /* @__PURE__ */ new Set();
547
+ function registerSink(sink) {
548
+ if (!sinks.has(sink.name)) sinkOrder.push(sink.name);
549
+ sinks.set(sink.name, sink);
550
+ }
551
+ if (config.endpoint) {
552
+ registerSink(
553
+ createHttpSink({
554
+ endpoint: config.endpoint,
555
+ writeKey: config.writeKey ?? "",
556
+ // One clock for the whole manager: the auto sink stamps sentAt with it too.
557
+ now
558
+ })
559
+ );
560
+ }
561
+ if (preset === "dev") {
562
+ registerSink(createConsoleSink());
563
+ }
564
+ for (const s of config.sinks ?? []) registerSink(s);
565
+ function ensureInit(sink) {
566
+ if (initialized.has(sink.name)) return;
567
+ initialized.add(sink.name);
568
+ if (sink.init) {
569
+ return sink.init({ app, env, endpoint: config.endpoint });
570
+ }
571
+ }
572
+ const buffer = [];
573
+ let timer;
574
+ function startTimer() {
575
+ if (preset !== "prod" || timer) return;
576
+ timer = setInterval(() => {
577
+ void flush(false);
578
+ }, flushIntervalMs);
579
+ timer.unref?.();
580
+ }
581
+ function deliverToSinks(batch, unload) {
582
+ if (batch.length === 0) return;
583
+ const ctx = { unload };
584
+ const pending = [];
585
+ for (const name of sinkOrder) {
586
+ const sink = sinks.get(name);
587
+ if (!sink) continue;
588
+ if (!consent.allows(sink.consentCategories)) continue;
589
+ const inited = ensureInit(sink);
590
+ if (inited && typeof inited.then === "function") {
591
+ pending.push(
592
+ inited.then(() => sink.deliver(batch, ctx))
593
+ );
594
+ } else {
595
+ const r = sink.deliver(batch, ctx);
596
+ if (r && typeof r.then === "function") {
597
+ pending.push(r);
598
+ }
599
+ }
600
+ }
601
+ if (pending.length) return Promise.all(pending).then(() => void 0);
602
+ }
603
+ async function flush(unload = false) {
604
+ const batch = buffer.splice(0, buffer.length);
605
+ await deliverToSinks(batch, unload);
606
+ for (const name of sinkOrder) {
607
+ const sink = sinks.get(name);
608
+ if (sink?.flush && consent.allows(sink.consentCategories)) {
609
+ await sink.flush();
610
+ }
611
+ }
612
+ }
613
+ function bindUnload() {
614
+ if (preset !== "prod") return;
615
+ const g = globalThis;
616
+ if (typeof g.addEventListener !== "function") return;
617
+ const onUnload = () => {
618
+ void deliverToSinks(buffer.splice(0, buffer.length), true);
619
+ };
620
+ g.addEventListener("pagehide", onUnload);
621
+ g.addEventListener("visibilitychange", () => {
622
+ if (g.document?.visibilityState === "hidden") onUnload();
623
+ });
624
+ }
625
+ startTimer();
626
+ bindUnload();
627
+ function buildContext(extra, childCtx) {
628
+ const page = readPage();
629
+ return {
630
+ app,
631
+ env,
632
+ ...page ? { page } : {},
633
+ ...childCtx,
634
+ ...extra,
635
+ library: LIBRARY
636
+ };
637
+ }
638
+ function sampled() {
639
+ if (sampleRate >= 1) return true;
640
+ if (sampleRate <= 0) return false;
641
+ return random() < sampleRate;
642
+ }
643
+ function enqueue(ev) {
644
+ if (preset === "dev") {
645
+ void deliverToSinks([ev], false);
646
+ return;
647
+ }
648
+ buffer.push(ev);
649
+ if (buffer.length >= batchSize) {
650
+ void flush(false);
651
+ }
652
+ }
653
+ function emit(type, fields, childCtx, opts) {
654
+ if (!sampled()) return;
655
+ const page = readPage();
656
+ const campaign = campaignFingerprint(page?.search);
657
+ const sessionId = session.touch(campaign);
658
+ const sessionProps = session.props();
659
+ const ev = {
660
+ type,
661
+ messageId: uuidv4(),
662
+ anonymousId: identity.anonymousId(),
663
+ userId: identity.userId(),
664
+ sessionId,
665
+ context: buildContext(opts?.context, childCtx),
666
+ timestamp: opts?.timestamp ?? now().toISOString(),
667
+ schemaVersion: SCHEMA_VERSION,
668
+ ...fields
669
+ };
670
+ if (sessionProps && (ev.properties || type === "track" || type === "page" || type === "screen")) {
671
+ ev.properties = { ...sessionProps, ...ev.properties ?? {} };
672
+ }
673
+ enqueue(ev);
674
+ }
675
+ function makeApi(childCtx) {
676
+ const api = {
677
+ track(event, properties, opts) {
678
+ emit(
679
+ "track",
680
+ { event, properties: redactor.redact(properties) },
681
+ childCtx,
682
+ opts
683
+ );
684
+ },
685
+ identify(userId, traits, opts) {
686
+ identity.setUserId(userId);
687
+ emit("identify", { traits: redactor.redact(traits) }, childCtx, opts);
688
+ },
689
+ page(name, properties, opts) {
690
+ emit(
691
+ "page",
692
+ { event: name, properties: redactor.redact(properties) },
693
+ childCtx,
694
+ opts
695
+ );
696
+ },
697
+ screen(name, properties, opts) {
698
+ emit(
699
+ "screen",
700
+ { event: name, properties: redactor.redact(properties) },
701
+ childCtx,
702
+ opts
703
+ );
704
+ },
705
+ group(groupId, traits, opts) {
706
+ emit(
707
+ "group",
708
+ { groupId, traits: redactor.redact(traits) },
709
+ childCtx,
710
+ opts
711
+ );
712
+ },
713
+ alias(userId, previousId, opts) {
714
+ const stitch = identity.alias(userId, previousId);
715
+ emit(
716
+ "alias",
717
+ { userId: stitch.userId, previousId: stitch.previousId },
718
+ childCtx,
719
+ opts
720
+ );
721
+ },
722
+ session: {
723
+ id: () => session.id(),
724
+ start: () => session.start(),
725
+ end: () => session.end(),
726
+ set: (props) => session.set(props)
727
+ },
728
+ consent: {
729
+ grant: (...c) => consent.grant(...c),
730
+ revoke: (...c) => consent.revoke(...c),
731
+ granted: () => consent.granted(),
732
+ isGranted: (c) => consent.isGranted(c)
733
+ },
734
+ anonymousId: () => identity.anonymousId(),
735
+ userId: () => identity.userId(),
736
+ with(extra) {
737
+ return makeApi({ ...childCtx, ...extra });
738
+ },
739
+ addSink(sink) {
740
+ registerSink(sink);
741
+ },
742
+ removeSink(name) {
743
+ if (sinks.has(name)) {
744
+ sinks.delete(name);
745
+ const i = sinkOrder.indexOf(name);
746
+ if (i !== -1) sinkOrder.splice(i, 1);
747
+ initialized.delete(name);
748
+ }
749
+ },
750
+ get sinks() {
751
+ return [...sinkOrder];
752
+ },
753
+ async flush() {
754
+ await flush(false);
755
+ },
756
+ reset() {
757
+ identity.reset();
758
+ session.end();
759
+ },
760
+ enabled: true
761
+ };
762
+ return api;
763
+ }
764
+ return makeApi();
765
+ }
766
+
767
+ // ../analytics-sink-ga4/dist/index.js
768
+ var GA4_RESERVED_PREFIXES = ["google_", "ga_", "firebase_"];
769
+ function toGa4Name(name) {
770
+ const snake = name.trim().replace(/['"]/g, "").replace(/[^a-zA-Z0-9]+/g, "_").replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/_+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
771
+ const safe = /^[a-z]/.test(snake) ? snake : `e_${snake}`;
772
+ return GA4_RESERVED_PREFIXES.some((p) => safe.startsWith(p)) ? `x_${safe}` : safe;
773
+ }
774
+ function ga4EventName(ev) {
775
+ switch (ev.type) {
776
+ case "identify":
777
+ return void 0;
778
+ case "page":
779
+ return "page_view";
780
+ case "screen":
781
+ return "screen_view";
782
+ case "group":
783
+ return "group";
784
+ case "alias":
785
+ return "alias";
786
+ case "track":
787
+ return ev.event ? toGa4Name(ev.event) : "track";
788
+ default:
789
+ return void 0;
790
+ }
791
+ }
792
+ function toUserProperties(traits) {
793
+ if (!traits) return void 0;
794
+ const out = {};
795
+ let any = false;
796
+ for (const [k, v] of Object.entries(traits)) {
797
+ if (v === void 0) continue;
798
+ out[toGa4Name(k)] = { value: v };
799
+ any = true;
800
+ }
801
+ return any ? out : void 0;
802
+ }
803
+ function toParams(ev) {
804
+ const params = {};
805
+ for (const [k, v] of Object.entries(ev.properties ?? {})) {
806
+ if (v === void 0) continue;
807
+ params[toGa4Name(k)] = v;
808
+ }
809
+ params.session_id = ev.sessionId;
810
+ params.engagement_time_msec = params.engagement_time_msec ?? 1;
811
+ const page = ev.context.page;
812
+ if (ev.type === "page" || ev.type === "screen") {
813
+ if (ev.event) {
814
+ if (ev.type === "screen") params.screen_name = ev.event;
815
+ else params.page_title = params.page_title ?? ev.event;
816
+ }
817
+ if (page?.url && params.page_location === void 0) {
818
+ params.page_location = page.url;
819
+ }
820
+ if (page?.path && params.page_path === void 0) {
821
+ params.page_path = page.path;
822
+ }
823
+ if (page?.referrer && params.page_referrer === void 0) {
824
+ params.page_referrer = page.referrer;
825
+ }
826
+ if (page?.title && params.page_title === void 0) {
827
+ params.page_title = page.title;
828
+ }
829
+ }
830
+ if (ev.type === "group" && ev.groupId) {
831
+ params.group_id = ev.groupId;
832
+ }
833
+ if (ev.type === "alias") {
834
+ if (ev.userId) params.user_id = ev.userId;
835
+ if (ev.previousId) params.previous_id = ev.previousId;
836
+ }
837
+ return params;
838
+ }
839
+ function mapEvent(ev) {
840
+ const name = ga4EventName(ev);
841
+ const mapped = {
842
+ clientId: ev.anonymousId
843
+ };
844
+ if (ev.userId) mapped.userId = ev.userId;
845
+ if (ev.type === "identify" || ev.type === "group") {
846
+ const up = toUserProperties(ev.traits);
847
+ if (up) mapped.userProperties = up;
848
+ }
849
+ if (name) {
850
+ mapped.event = { name, params: toParams(ev) };
851
+ }
852
+ return mapped;
853
+ }
854
+ var DEFAULT_ENDPOINT = "https://www.google-analytics.com";
855
+ var MAX_EVENTS_PER_REQUEST = 25;
856
+ function resolveFetch(opts) {
857
+ if (opts.fetchImpl) return opts.fetchImpl;
858
+ const f = globalThis.fetch;
859
+ if (!f) throw new Error("GA4 http sink: no fetch implementation available");
860
+ return f;
861
+ }
862
+ function buildPayloads(batch) {
863
+ const payloads = [];
864
+ for (const ev of batch) {
865
+ const m = mapEvent(ev);
866
+ const last = payloads[payloads.length - 1];
867
+ const sameIdentity = last && last.client_id === m.clientId && last.user_id === m.userId && last.events.length < MAX_EVENTS_PER_REQUEST && // user_properties must not silently differ within one request
868
+ JSON.stringify(last.user_properties) === JSON.stringify(m.userProperties);
869
+ const target = sameIdentity ? last : (() => {
870
+ const p = { client_id: m.clientId, events: [] };
871
+ if (m.userId) p.user_id = m.userId;
872
+ if (m.userProperties) p.user_properties = m.userProperties;
873
+ payloads.push(p);
874
+ return p;
875
+ })();
876
+ if (m.event) {
877
+ target.events.push(m.event);
878
+ }
879
+ }
880
+ return payloads.filter(
881
+ (p) => p.events.length > 0 || p.user_id !== void 0 || p.user_properties !== void 0
882
+ );
883
+ }
884
+ function createGA4HttpSink(options) {
885
+ const {
886
+ measurementId,
887
+ apiSecret,
888
+ consentCategories = ["analytics"],
889
+ name = "ga4",
890
+ debug = false
891
+ } = options;
892
+ const base = (options.endpoint ?? DEFAULT_ENDPOINT).replace(/\/+$/, "");
893
+ const path = debug ? "/debug/mp/collect" : "/mp/collect";
894
+ const url = `${base}${path}?measurement_id=${encodeURIComponent(measurementId)}&api_secret=${encodeURIComponent(apiSecret)}`;
895
+ return {
896
+ name,
897
+ consentCategories,
898
+ init(_ctx) {
899
+ },
900
+ async deliver(batch) {
901
+ if (batch.length === 0) return;
902
+ const payloads = buildPayloads(batch);
903
+ if (payloads.length === 0) return;
904
+ const doFetch = resolveFetch(options);
905
+ for (const payload of payloads) {
906
+ try {
907
+ await doFetch(url, {
908
+ method: "POST",
909
+ headers: { "Content-Type": "application/json" },
910
+ body: JSON.stringify(payload),
911
+ keepalive: true
912
+ });
913
+ } catch {
914
+ }
915
+ }
916
+ }
917
+ };
918
+ }
919
+ var DEFAULT_SRC_BASE = "https://www.googletagmanager.com/gtag/js";
920
+ function defaultScriptLoader(src) {
921
+ const g = globalThis;
922
+ const doc = g.document;
923
+ if (!doc || typeof doc.createElement !== "function") {
924
+ return Promise.reject(
925
+ new Error("GA4 client-sdk sink: no DOM to inject gtag.js")
926
+ );
927
+ }
928
+ return new Promise((resolve, reject) => {
929
+ const el = doc.createElement("script");
930
+ el.async = true;
931
+ el.src = src;
932
+ el.onload = () => resolve();
933
+ el.onerror = () => reject(new Error("GA4 client-sdk: gtag.js failed"));
934
+ if (doc.head?.appendChild) {
935
+ doc.head.appendChild(el);
936
+ } else {
937
+ const first = doc.getElementsByTagName("script")[0];
938
+ first?.parentNode?.insertBefore(el, first);
939
+ }
940
+ });
941
+ }
942
+ function createGA4ClientSdkSink(options) {
943
+ const {
944
+ measurementId,
945
+ consentCategories = ["analytics"],
946
+ name = "ga4",
947
+ consentMode
948
+ } = options;
949
+ const g = globalThis;
950
+ let gtag = options.gtag;
951
+ let loaded = false;
952
+ let loadPromise;
953
+ function ensureGtagStub() {
954
+ if (gtag) return gtag;
955
+ g.dataLayer = g.dataLayer ?? [];
956
+ const dl = g.dataLayer;
957
+ const fn = (...args) => {
958
+ dl.push(args);
959
+ };
960
+ g.gtag = g.gtag ?? fn;
961
+ gtag = g.gtag;
962
+ return gtag;
963
+ }
964
+ function pushConsentDefault() {
965
+ if (!consentMode?.default || !gtag) return;
966
+ gtag("consent", "default", { ...consentMode.default });
967
+ }
968
+ function pushConsentUpdate() {
969
+ if (!consentMode?.map || !gtag) return;
970
+ const update = {};
971
+ for (const cat of consentCategories) {
972
+ for (const ga4Type of consentMode.map[cat] ?? []) {
973
+ update[ga4Type] = "granted";
974
+ }
975
+ }
976
+ if (Object.keys(update).length > 0) {
977
+ gtag("consent", "update", update);
978
+ }
979
+ }
980
+ function ensureLoaded() {
981
+ if (loaded) return Promise.resolve();
982
+ if (loadPromise) return loadPromise;
983
+ ensureGtagStub();
984
+ pushConsentDefault();
985
+ if (options.gtag) {
986
+ gtag("js", /* @__PURE__ */ new Date());
987
+ gtag("config", measurementId, { send_page_view: false });
988
+ loaded = true;
989
+ return Promise.resolve();
990
+ }
991
+ const base = options.gtagSrcBase ?? DEFAULT_SRC_BASE;
992
+ const src = `${base}?id=${encodeURIComponent(measurementId)}`;
993
+ const load = options.scriptLoader ?? defaultScriptLoader;
994
+ loadPromise = load(src).then(() => {
995
+ gtag("js", /* @__PURE__ */ new Date());
996
+ gtag("config", measurementId, { send_page_view: false });
997
+ loaded = true;
998
+ });
999
+ return loadPromise;
1000
+ }
1001
+ return {
1002
+ name,
1003
+ consentCategories,
1004
+ init(_ctx) {
1005
+ ensureGtagStub();
1006
+ pushConsentDefault();
1007
+ },
1008
+ async deliver(batch) {
1009
+ if (batch.length === 0) return;
1010
+ await ensureLoaded();
1011
+ const send = gtag;
1012
+ pushConsentUpdate();
1013
+ for (const ev of batch) {
1014
+ const m = mapEvent(ev);
1015
+ if (m.userId) {
1016
+ send("set", { user_id: m.userId });
1017
+ }
1018
+ if (m.userProperties) {
1019
+ const flat = {};
1020
+ for (const [k, v] of Object.entries(m.userProperties)) {
1021
+ flat[k] = v.value;
1022
+ }
1023
+ send("set", "user_properties", flat);
1024
+ }
1025
+ if (m.event) {
1026
+ send("event", m.event.name, m.event.params);
1027
+ }
1028
+ }
1029
+ }
1030
+ };
1031
+ }
1032
+ function createGA4Sink(options) {
1033
+ if (options.mode === "client-sdk") {
1034
+ return createGA4ClientSdkSink(options);
1035
+ }
1036
+ return createGA4HttpSink(options);
1037
+ }
1038
+
1039
+ // ../analytics-sink-app-insights/dist/index.js
1040
+ var FALLBACK_TRACK_NAME = "track";
1041
+ function eventName(ev) {
1042
+ switch (ev.type) {
1043
+ case "page":
1044
+ return `Page View: ${ev.event ?? ev.context.page?.path ?? "(unknown)"}`;
1045
+ case "screen":
1046
+ return `Screen: ${ev.event ?? "(unknown)"}`;
1047
+ case "identify":
1048
+ return "Identify";
1049
+ case "group":
1050
+ return "Group";
1051
+ case "alias":
1052
+ return "Alias";
1053
+ case "track":
1054
+ default:
1055
+ return ev.event ?? FALLBACK_TRACK_NAME;
1056
+ }
1057
+ }
1058
+ function isMeasurement(value) {
1059
+ return typeof value === "number" && Number.isFinite(value);
1060
+ }
1061
+ function stringify(value) {
1062
+ if (typeof value === "string") return value;
1063
+ if (typeof value === "boolean" || typeof value === "bigint") {
1064
+ return String(value);
1065
+ }
1066
+ if (typeof value === "number") return String(value);
1067
+ try {
1068
+ return JSON.stringify(value) ?? String(value);
1069
+ } catch {
1070
+ return String(value);
1071
+ }
1072
+ }
1073
+ function splitBag(bag, prefix, properties, measurements) {
1074
+ if (!bag) return;
1075
+ for (const [key, value] of Object.entries(bag)) {
1076
+ if (value === void 0 || value === null) continue;
1077
+ const flatKey = prefix ? `${prefix}.${key}` : key;
1078
+ if (isMeasurement(value)) {
1079
+ measurements[flatKey] = value;
1080
+ continue;
1081
+ }
1082
+ if (typeof value === "object" && !Array.isArray(value) && value.constructor === Object) {
1083
+ splitBag(
1084
+ value,
1085
+ flatKey,
1086
+ properties,
1087
+ measurements
1088
+ );
1089
+ continue;
1090
+ }
1091
+ properties[flatKey] = stringify(value);
1092
+ }
1093
+ }
1094
+ function mapEvent2(ev) {
1095
+ const properties = {};
1096
+ const measurements = {};
1097
+ if (ev.userId !== void 0) {
1098
+ properties.authenticatedUserId = ev.userId;
1099
+ properties.anonymous = "false";
1100
+ } else {
1101
+ properties.anonymous = "true";
1102
+ }
1103
+ properties.messageId = ev.messageId;
1104
+ properties.anonymousId = ev.anonymousId;
1105
+ properties.sessionId = ev.sessionId;
1106
+ properties.eventType = ev.type;
1107
+ properties.timestamp = ev.timestamp;
1108
+ measurements.schemaVersion = ev.schemaVersion;
1109
+ if (ev.groupId !== void 0) properties.groupId = ev.groupId;
1110
+ if (ev.previousId !== void 0) properties.previousId = ev.previousId;
1111
+ if (ev.event !== void 0) properties.eventName = ev.event;
1112
+ properties.app = ev.context.app;
1113
+ properties.env = ev.context.env;
1114
+ properties.libraryName = ev.context.library.name;
1115
+ properties.libraryVersion = ev.context.library.version;
1116
+ if (ev.context.page) {
1117
+ splitBag(
1118
+ ev.context.page,
1119
+ "page",
1120
+ properties,
1121
+ measurements
1122
+ );
1123
+ }
1124
+ splitBag(ev.properties, "", properties, measurements);
1125
+ splitBag(ev.traits, "", properties, measurements);
1126
+ return { name: eventName(ev), properties, measurements };
1127
+ }
1128
+ var DEFAULT_INGEST_ENDPOINT = "https://dc.services.visualstudio.com";
1129
+ var NO_RETRY2 = /* @__PURE__ */ new Set([400, 401, 403, 413]);
1130
+ var sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
1131
+ var appInsightsWebSpecifier = "@microsoft/applicationinsights-web";
1132
+ function createClientSdkSink(opts) {
1133
+ const name = opts.name ?? "app-insights";
1134
+ let instance = opts.appInsights;
1135
+ let loading;
1136
+ async function resolveSdk() {
1137
+ if (instance) return instance;
1138
+ if (loading) return loading;
1139
+ loading = (async () => {
1140
+ if (opts.loadSdk) {
1141
+ instance = await opts.loadSdk({
1142
+ connectionString: opts.connectionString,
1143
+ instrumentationKey: opts.instrumentationKey
1144
+ });
1145
+ return instance;
1146
+ }
1147
+ const mod = await import(appInsightsWebSpecifier);
1148
+ const ai = new mod.ApplicationInsights({
1149
+ config: {
1150
+ connectionString: opts.connectionString,
1151
+ instrumentationKey: opts.instrumentationKey
1152
+ }
1153
+ });
1154
+ ai.loadAppInsights?.();
1155
+ instance = ai;
1156
+ return ai;
1157
+ })();
1158
+ return loading;
1159
+ }
1160
+ let lastAuthUserId;
1161
+ return {
1162
+ name,
1163
+ consentCategories: opts.consentCategories ?? ["analytics"],
1164
+ async deliver(batch) {
1165
+ if (batch.length === 0) return;
1166
+ const ai = await resolveSdk();
1167
+ for (const ev of batch) {
1168
+ if (ev.userId !== void 0 && ev.userId !== lastAuthUserId) {
1169
+ ai.setAuthenticatedUserContext?.(ev.userId);
1170
+ lastAuthUserId = ev.userId;
1171
+ }
1172
+ if (ev.type === "identify" && ev.userId === void 0 && lastAuthUserId !== void 0) {
1173
+ ai.clearAuthenticatedUserContext?.();
1174
+ lastAuthUserId = void 0;
1175
+ }
1176
+ const mapped = mapEvent2(ev);
1177
+ const merged = {
1178
+ ...mapped.properties,
1179
+ ...mapped.measurements
1180
+ };
1181
+ if (ev.type === "page") {
1182
+ ai.trackPageView({
1183
+ name: ev.event ?? ev.context.page?.path,
1184
+ uri: ev.context.page?.url,
1185
+ properties: mapped.properties,
1186
+ measurements: mapped.measurements
1187
+ });
1188
+ } else {
1189
+ ai.trackEvent({ name: mapped.name }, merged);
1190
+ }
1191
+ }
1192
+ },
1193
+ async flush() {
1194
+ if (instance?.flush) instance.flush(false);
1195
+ },
1196
+ shutdown() {
1197
+ instance = void 0;
1198
+ loading = void 0;
1199
+ lastAuthUserId = void 0;
1200
+ }
1201
+ };
1202
+ }
1203
+ function buildIngestEnvelope(ev, iKey) {
1204
+ const mapped = mapEvent2(ev);
1205
+ const isPage = ev.type === "page";
1206
+ const tags = {
1207
+ "ai.session.id": ev.sessionId,
1208
+ "ai.user.id": ev.anonymousId,
1209
+ "ai.operation.id": ev.messageId,
1210
+ "ai.internal.sdkVersion": `refraction-ui-analytics-app-insights:0.1.0`,
1211
+ "ai.application.ver": ev.context.library.version,
1212
+ "ai.cloud.role": ev.context.app,
1213
+ "ai.cloud.roleInstance": ev.context.env
1214
+ };
1215
+ if (ev.userId !== void 0) tags["ai.user.authUserId"] = ev.userId;
1216
+ return {
1217
+ name: isPage ? "Microsoft.ApplicationInsights.PageView" : "Microsoft.ApplicationInsights.Event",
1218
+ time: ev.timestamp,
1219
+ iKey,
1220
+ tags,
1221
+ data: {
1222
+ baseType: isPage ? "PageViewData" : "EventData",
1223
+ baseData: {
1224
+ ver: 2,
1225
+ name: isPage ? eventName(ev) : mapped.name,
1226
+ properties: mapped.properties,
1227
+ measurements: mapped.measurements
1228
+ }
1229
+ }
1230
+ };
1231
+ }
1232
+ function createHttpSink2(opts) {
1233
+ const name = opts.name ?? "app-insights";
1234
+ const {
1235
+ instrumentationKey,
1236
+ maxRetries = 3,
1237
+ backoffBaseMs = 500
1238
+ } = opts;
1239
+ const base = (opts.endpoint ?? DEFAULT_INGEST_ENDPOINT).replace(/\/+$/, "");
1240
+ const url = `${base}/v2/track`;
1241
+ const resolveFetch2 = () => {
1242
+ if (opts.fetchImpl) return opts.fetchImpl;
1243
+ const f = globalThis.fetch;
1244
+ if (!f) throw new Error("No fetch implementation available");
1245
+ return f;
1246
+ };
1247
+ async function send(body) {
1248
+ const doFetch = resolveFetch2();
1249
+ for (let attempt = 0; ; attempt++) {
1250
+ let status;
1251
+ try {
1252
+ const res = await doFetch(url, {
1253
+ method: "POST",
1254
+ headers: { "Content-Type": "application/json" },
1255
+ body,
1256
+ keepalive: true
1257
+ });
1258
+ status = res.status;
1259
+ } catch {
1260
+ status = 0;
1261
+ }
1262
+ if (status >= 200 && status < 300) return;
1263
+ if (NO_RETRY2.has(status)) return;
1264
+ if (attempt >= maxRetries) return;
1265
+ await sleep2(backoffBaseMs * 2 ** attempt);
1266
+ }
1267
+ }
1268
+ return {
1269
+ name,
1270
+ consentCategories: opts.consentCategories ?? ["analytics"],
1271
+ async deliver(batch, _ctx) {
1272
+ if (batch.length === 0) return;
1273
+ const envelopes = batch.map(
1274
+ (ev) => buildIngestEnvelope(ev, instrumentationKey)
1275
+ );
1276
+ await send(JSON.stringify(envelopes));
1277
+ }
1278
+ };
1279
+ }
1280
+ function createAppInsightsSink(options) {
1281
+ return options.mode === "http" ? createHttpSink2(options) : createClientSdkSink(options);
1282
+ }
1283
+
1284
+ // ../analytics-sink-posthog/dist/index.js
1285
+ function distinctId(ev) {
1286
+ return ev.userId ?? ev.anonymousId;
1287
+ }
1288
+ function contextProperties(ev) {
1289
+ const ctx = ev.context;
1290
+ const props = {
1291
+ $lib: ctx.library?.name,
1292
+ $lib_version: ctx.library?.version,
1293
+ app: ctx.app,
1294
+ env: ctx.env,
1295
+ $session_id: ev.sessionId,
1296
+ // Keep the canonical anonymous id addressable in PostHog too.
1297
+ anonymousId: ev.anonymousId
1298
+ };
1299
+ const page = ctx.page;
1300
+ if (page) {
1301
+ if (page.url !== void 0) props.$current_url = page.url;
1302
+ if (page.path !== void 0) props.$pathname = page.path;
1303
+ if (page.referrer !== void 0) props.$referrer = page.referrer;
1304
+ if (page.title !== void 0) props.title = page.title;
1305
+ if (page.search !== void 0) props.$search = page.search;
1306
+ }
1307
+ return props;
1308
+ }
1309
+ function toPostHogEvent(ev) {
1310
+ const base = {
1311
+ distinct_id: distinctId(ev),
1312
+ timestamp: ev.timestamp,
1313
+ uuid: ev.messageId
1314
+ };
1315
+ const props = contextProperties(ev);
1316
+ switch (ev.type) {
1317
+ case "identify": {
1318
+ return {
1319
+ ...base,
1320
+ event: "$identify",
1321
+ properties: {
1322
+ ...props,
1323
+ $set: { ...ev.traits ?? {} },
1324
+ // Stitch the pre-identify anonymous history onto this person.
1325
+ $anon_distinct_id: ev.anonymousId
1326
+ }
1327
+ };
1328
+ }
1329
+ case "group": {
1330
+ const groupType = ev.properties?.groupType ?? "company";
1331
+ return {
1332
+ ...base,
1333
+ event: "$groupidentify",
1334
+ properties: {
1335
+ ...props,
1336
+ $group_type: groupType,
1337
+ $group_key: ev.groupId,
1338
+ $group_set: { ...ev.traits ?? {} }
1339
+ }
1340
+ };
1341
+ }
1342
+ case "alias": {
1343
+ return {
1344
+ ...base,
1345
+ event: "$create_alias",
1346
+ properties: {
1347
+ ...props,
1348
+ // PostHog links `alias` to the current `distinct_id`.
1349
+ alias: ev.previousId
1350
+ }
1351
+ };
1352
+ }
1353
+ case "page": {
1354
+ return {
1355
+ ...base,
1356
+ event: "$pageview",
1357
+ properties: { ...props, ...ev.properties ?? {} }
1358
+ };
1359
+ }
1360
+ case "screen": {
1361
+ return {
1362
+ ...base,
1363
+ event: "$screen",
1364
+ properties: {
1365
+ ...props,
1366
+ $screen_name: ev.event,
1367
+ ...ev.properties ?? {}
1368
+ }
1369
+ };
1370
+ }
1371
+ case "track":
1372
+ default: {
1373
+ return {
1374
+ ...base,
1375
+ event: ev.event ?? "track",
1376
+ properties: { ...props, ...ev.properties ?? {} }
1377
+ };
1378
+ }
1379
+ }
1380
+ }
1381
+ function toPostHogBatch(batch) {
1382
+ return batch.map(toPostHogEvent);
1383
+ }
1384
+ var NO_RETRY3 = /* @__PURE__ */ new Set([400, 401, 403, 413]);
1385
+ var sleep3 = (ms) => new Promise((r) => setTimeout(r, ms));
1386
+ function byteLength2(s) {
1387
+ const g = globalThis;
1388
+ if (g.TextEncoder) return new g.TextEncoder().encode(s).length;
1389
+ return unescape(encodeURIComponent(s)).length;
1390
+ }
1391
+ function splitBatch2(items, maxBatchBytes, maxEventBytes) {
1392
+ const batches = [];
1393
+ let current = [];
1394
+ let currentBytes = 2;
1395
+ for (const item of items) {
1396
+ const itemBytes = byteLength2(JSON.stringify(item));
1397
+ if (itemBytes > maxEventBytes) continue;
1398
+ if (current.length && currentBytes + itemBytes + 1 > maxBatchBytes) {
1399
+ batches.push(current);
1400
+ current = [];
1401
+ currentBytes = 2;
1402
+ }
1403
+ current.push(item);
1404
+ currentBytes += itemBytes + 1;
1405
+ }
1406
+ if (current.length) batches.push(current);
1407
+ return batches;
1408
+ }
1409
+ function createPostHogHttpSink(options) {
1410
+ const {
1411
+ apiKey,
1412
+ host = "https://us.i.posthog.com",
1413
+ name = "posthog",
1414
+ consentCategories = ["analytics"],
1415
+ maxRetries = 3,
1416
+ backoffBaseMs = 500,
1417
+ maxBatchBytes = 1e6,
1418
+ maxEventBytes = 32e3
1419
+ } = options;
1420
+ const base = host.replace(/\/+$/, "");
1421
+ const captureUrl = `${base}/capture/`;
1422
+ const batchUrl = `${base}/batch/`;
1423
+ const resolveFetch2 = () => {
1424
+ if (options.fetchImpl) return options.fetchImpl;
1425
+ const f = globalThis.fetch;
1426
+ if (!f) throw new Error("No fetch implementation available");
1427
+ return f;
1428
+ };
1429
+ const resolveBeacon = () => {
1430
+ if (options.beaconImpl) return options.beaconImpl;
1431
+ const nav = globalThis.navigator;
1432
+ if (nav && typeof nav.sendBeacon === "function") {
1433
+ return (u, body) => nav.sendBeacon(u, body);
1434
+ }
1435
+ return void 0;
1436
+ };
1437
+ function payload(part) {
1438
+ if (part.length === 1) {
1439
+ return {
1440
+ url: captureUrl,
1441
+ body: JSON.stringify({ api_key: apiKey, ...part[0] })
1442
+ };
1443
+ }
1444
+ return {
1445
+ url: batchUrl,
1446
+ body: JSON.stringify({ api_key: apiKey, batch: part })
1447
+ };
1448
+ }
1449
+ async function sendViaFetch(part) {
1450
+ const doFetch = resolveFetch2();
1451
+ const { url, body } = payload(part);
1452
+ for (let attempt = 0; ; attempt++) {
1453
+ let status;
1454
+ try {
1455
+ const res = await doFetch(url, {
1456
+ method: "POST",
1457
+ headers: { "Content-Type": "application/json" },
1458
+ body,
1459
+ keepalive: true
1460
+ });
1461
+ status = res.status;
1462
+ } catch {
1463
+ status = 0;
1464
+ }
1465
+ if (status >= 200 && status < 300) return;
1466
+ if (NO_RETRY3.has(status)) return;
1467
+ if (attempt >= maxRetries) return;
1468
+ await sleep3(backoffBaseMs * 2 ** attempt);
1469
+ }
1470
+ }
1471
+ function sendViaBeacon(part) {
1472
+ const beacon = resolveBeacon();
1473
+ if (!beacon) return false;
1474
+ const { url, body } = payload(part);
1475
+ return beacon(url, body);
1476
+ }
1477
+ return {
1478
+ name,
1479
+ consentCategories,
1480
+ async deliver(batch, ctx) {
1481
+ if (batch.length === 0) return;
1482
+ const items = toPostHogBatch(batch);
1483
+ const parts = splitBatch2(items, maxBatchBytes, maxEventBytes);
1484
+ for (const part of parts) {
1485
+ if (part.length === 0) continue;
1486
+ if (ctx.unload) {
1487
+ if (sendViaBeacon(part)) continue;
1488
+ void sendViaFetch(part);
1489
+ } else {
1490
+ await sendViaFetch(part);
1491
+ }
1492
+ }
1493
+ }
1494
+ };
1495
+ }
1496
+ var posthogJsSpecifier = "posthog-js";
1497
+ async function defaultLoad() {
1498
+ const mod = await import(posthogJsSpecifier);
1499
+ return "default" in mod ? mod.default : mod;
1500
+ }
1501
+ function createPostHogClientSdkSink(options) {
1502
+ const {
1503
+ apiKey,
1504
+ host = "https://us.i.posthog.com",
1505
+ name = "posthog",
1506
+ consentCategories = ["analytics"],
1507
+ posthogOptions = {}
1508
+ } = options;
1509
+ let ph;
1510
+ let loading;
1511
+ async function ensure() {
1512
+ if (ph) return ph;
1513
+ if (!loading) {
1514
+ const load = options.loadPostHog ? async () => {
1515
+ const m = await options.loadPostHog();
1516
+ return "default" in m ? m.default : m;
1517
+ } : defaultLoad;
1518
+ loading = load().then((instance) => {
1519
+ instance.init(apiKey, {
1520
+ api_host: host,
1521
+ // The canonical router owns the event path — disable PostHog's
1522
+ // own auto-capture and pageview, and never start replay here.
1523
+ autocapture: false,
1524
+ capture_pageview: false,
1525
+ disable_session_recording: true,
1526
+ ...posthogOptions
1527
+ });
1528
+ ph = instance;
1529
+ return instance;
1530
+ });
1531
+ }
1532
+ return loading;
1533
+ }
1534
+ return {
1535
+ name,
1536
+ consentCategories,
1537
+ async init(_ctx) {
1538
+ await ensure();
1539
+ },
1540
+ async deliver(batch) {
1541
+ if (batch.length === 0) return;
1542
+ const client = await ensure();
1543
+ for (const ev of batch) {
1544
+ const did = distinctId(ev);
1545
+ switch (ev.type) {
1546
+ case "identify":
1547
+ client.identify(did, { ...ev.traits ?? {} });
1548
+ break;
1549
+ case "alias":
1550
+ if (ev.previousId) client.alias(ev.previousId, did);
1551
+ break;
1552
+ case "group":
1553
+ client.group(
1554
+ ev.properties?.groupType ?? "company",
1555
+ ev.groupId ?? "",
1556
+ { ...ev.traits ?? {} }
1557
+ );
1558
+ break;
1559
+ case "page":
1560
+ client.capture("$pageview", { ...ev.properties ?? {} });
1561
+ break;
1562
+ case "screen":
1563
+ client.capture("$screen", {
1564
+ $screen_name: ev.event,
1565
+ ...ev.properties ?? {}
1566
+ });
1567
+ break;
1568
+ case "track":
1569
+ default:
1570
+ client.capture(ev.event ?? "track", { ...ev.properties ?? {} });
1571
+ break;
1572
+ }
1573
+ }
1574
+ },
1575
+ shutdown() {
1576
+ ph?.reset();
1577
+ }
1578
+ };
1579
+ }
1580
+ function createPostHogSink(options) {
1581
+ if (options.mode === "client-sdk") {
1582
+ return createPostHogClientSdkSink(options);
1583
+ }
1584
+ return createPostHogHttpSink(options);
1585
+ }
1586
+
1587
+ // ../analytics-sink-posthog/dist/replay.js
1588
+ var posthogJsSpecifier2 = "posthog-js";
1589
+ async function defaultLoad2() {
1590
+ const mod = await import(posthogJsSpecifier2);
1591
+ return "default" in mod ? mod.default : mod;
1592
+ }
1593
+ async function startSessionReplay(options) {
1594
+ const {
1595
+ apiKey,
1596
+ host = "https://us.i.posthog.com",
1597
+ hasConsent,
1598
+ maskAllText = true,
1599
+ maskAllInputs = true,
1600
+ recordingOptions = {}
1601
+ } = options;
1602
+ const consented = () => typeof hasConsent === "function" ? hasConsent() === true : false;
1603
+ const slot = {};
1604
+ let recording = false;
1605
+ const stop = () => {
1606
+ if (slot.ph && recording) {
1607
+ slot.ph.stopSessionRecording();
1608
+ }
1609
+ recording = false;
1610
+ };
1611
+ const handle = {
1612
+ get recording() {
1613
+ return recording;
1614
+ },
1615
+ enforceConsent() {
1616
+ if (!consented()) stop();
1617
+ },
1618
+ stop
1619
+ };
1620
+ if (!consented()) return handle;
1621
+ const load = options.loadPostHog ? async () => {
1622
+ const m = await options.loadPostHog();
1623
+ return "default" in m ? m.default : m;
1624
+ } : defaultLoad2;
1625
+ slot.ph = await load();
1626
+ slot.ph.init(apiKey, {
1627
+ api_host: host,
1628
+ autocapture: false,
1629
+ capture_pageview: false,
1630
+ // Start with replay disabled, then opt in explicitly below.
1631
+ disable_session_recording: true,
1632
+ session_recording: {
1633
+ maskAllInputs,
1634
+ maskTextSelector: maskAllText ? "*" : void 0,
1635
+ ...recordingOptions
1636
+ }
1637
+ });
1638
+ if (!consented()) return handle;
1639
+ slot.ph.startSessionRecording();
1640
+ recording = slot.ph.sessionRecordingStarted?.() ?? true;
1641
+ return handle;
1642
+ }
1643
+
1644
+ // ../react-analytics/dist/index.js
1645
+ var AnalyticsContext = React.createContext(null);
1646
+ var noopAnalytics = null;
1647
+ function getNoopAnalytics() {
1648
+ return noopAnalytics ??= createNoopAnalytics();
1649
+ }
1650
+ function AnalyticsProvider({ children, value }) {
1651
+ const analyticsRef = React.useRef(null);
1652
+ if (!analyticsRef.current) {
1653
+ analyticsRef.current = value;
1654
+ }
1655
+ return React.createElement(
1656
+ AnalyticsContext.Provider,
1657
+ { value: analyticsRef.current },
1658
+ children
1659
+ );
1660
+ }
1661
+ function useAnalytics(options) {
1662
+ const ctx = React.useContext(AnalyticsContext);
1663
+ let base = ctx;
1664
+ if (!base) {
1665
+ devWarn(
1666
+ "react-analytics/use-analytics-outside-provider",
1667
+ "useAnalytics() (or useTrackEvent()) was called outside an <AnalyticsProvider>. Analytics is a no-op here; wrap your app (or the consuming subtree) in <AnalyticsProvider> to enable it."
1668
+ );
1669
+ base = getNoopAnalytics();
1670
+ }
1671
+ const scope = options?.scope;
1672
+ return React.useMemo(
1673
+ () => scope ? base.with(scope) : base,
1674
+ [base, scope]
1675
+ );
1676
+ }
1677
+ function useTrackEvent(options) {
1678
+ const analytics = useAnalytics(options);
1679
+ return React.useCallback(
1680
+ (event, properties, opts) => analytics.track(event, properties, opts),
1681
+ [analytics]
1682
+ );
1683
+ }
1684
+ export {
1685
+ AnalyticsProvider,
1686
+ createAnalytics,
1687
+ createAppInsightsSink,
1688
+ createGA4ClientSdkSink,
1689
+ createGA4HttpSink,
1690
+ createGA4Sink,
1691
+ createPostHogClientSdkSink,
1692
+ createPostHogHttpSink,
1693
+ createPostHogSink,
1694
+ startSessionReplay,
1695
+ useAnalytics,
1696
+ useTrackEvent
1697
+ };
1698
+ //# sourceMappingURL=react-analytics.js.map