@aranova/tracking-react 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -176,13 +176,70 @@ npx @aranova/tracking-cli gen # reads ARANOVA_TRACKING_SECRET_KEY from
176
176
  See the full guide: [sales-tracking.md](https://github.com/AranovaIO/aranova_internal/blob/master/docs/tracking-package/sales-tracking.md)
177
177
  and the CLI reference: [cli.md](https://github.com/AranovaIO/aranova_internal/blob/master/docs/tracking-package/cli.md).
178
178
 
179
+ ## Consent UI
180
+
181
+ The bundled `<ConsentBanner />` renders a non-blocking bottom-docked banner while consent is `pending`, persists the visitor's choice to `localStorage`, and propagates it to Google Consent Mode v2 when gtag is loaded. **Inline-styled** — no Tailwind or CSS imports required at the consumer.
182
+
183
+ ```tsx
184
+ import { ConsentBanner } from '@aranova/tracking-react';
185
+
186
+ // Drop-in, defaults work everywhere
187
+ <ConsentBanner />
188
+ ```
189
+
190
+ All props are optional:
191
+
192
+ ```tsx
193
+ <ConsentBanner
194
+ title="Cookies"
195
+ message="We use cookies to track ad performance."
196
+ acceptLabel="Sure"
197
+ declineLabel="No thanks"
198
+ policyHref="/privacy"
199
+ policyLabel="Privacy policy" // default: "Learn more"
200
+ onAccept={() => track('consent_accepted')}
201
+ onDecline={() => track('consent_declined')}
202
+ position="bottom" // or "top"
203
+ theme="light" // "light" | "dark" | "auto"
204
+ className="my-extra-classes"
205
+ style={{ background: '#fafafa' }} // wins over the theme defaults
206
+ />
207
+ ```
208
+
209
+ ### Fully custom UI — `useConsent()`
210
+
211
+ For a bespoke banner, skip the component and drive your own UI with the headless hook:
212
+
213
+ ```tsx
214
+ import { useConsent } from '@aranova/tracking-react';
215
+
216
+ function CookieBar() {
217
+ const { state, accept, decline, reset, isPending } = useConsent();
218
+
219
+ if (!isPending) {
220
+ // Footer link: re-open the banner if they change their mind.
221
+ return <button onClick={reset}>Cookie preferences</button>;
222
+ }
223
+ return (
224
+ <MyBespokeBanner>
225
+ <button onClick={decline}>No thanks</button>
226
+ <button onClick={accept}>Sure</button>
227
+ </MyBespokeBanner>
228
+ );
229
+ }
230
+ ```
231
+
232
+ The hook handles localStorage persistence, gtag sync, and cross-tab propagation — same machinery the default banner uses. `resetConsent()` is also exported as a standalone for non-component contexts.
233
+
179
234
  ## Exports
180
235
 
181
236
  - `createTracking()`
182
237
  - `TrackingProvider` and scoped `useTracking`
183
238
  - `GoogleAdsTracking`
184
- - `ConsentBanner`
185
- - `useTrackingParams()`, `useGclid()`, `useConsentState()`
239
+ - `ConsentBanner` + `ConsentBannerProps`
240
+ - Consent hooks: `useConsent()` + `UseConsentResult` (headless); `useConsentState()` (read-only alias)
241
+ - Standalone consent helpers: `getConsentState()`, `setConsentState()`, `resetConsent()`
242
+ - Attribution hooks: `useTrackingParams()`, `useGclid()`
186
243
  - `createSalesClient()` (isomorphic sales client — public key writes, secret key reads/CRUD) + money helpers (`toMinor`/`fromMinor`/`formatMoney`)
187
244
  - Codegen: [`@aranova/tracking-cli`](https://www.npmjs.com/package/@aranova/tracking-cli) — `gen` typed service unions (devDependency)
188
245
  - Event metadata/config types such as `FormSubmitMetadata`, `PhoneClickMetadata`, and `JsonValue`
package/dist/index.d.mts CHANGED
@@ -1,15 +1,71 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode } from 'react';
1
+ import { ReactNode, CSSProperties } from 'react';
3
2
  import * as src from 'src';
4
3
  import { z } from 'zod';
5
4
 
6
5
  /**
7
6
  * Default non-blocking consent banner.
8
7
  *
9
- * Renders only while consent is `pending`. Accept/decline choices are stored
10
- * in localStorage and propagated to Google Consent Mode when gtag is loaded.
11
- */
12
- declare function ConsentBanner(): react_jsx_runtime.JSX.Element | null;
8
+ * Renders only while consent is `pending`; collapses to `null` once the
9
+ * visitor has chosen.
10
+ *
11
+ * **Styling is intentionally self-contained** — inline styles, zero CSS
12
+ * dependencies, no Tailwind required at the consumer. The Tailwind-based
13
+ * banner shipped before 0.9.1 rendered as transparent in any consumer that
14
+ * didn't configure their content array to scan
15
+ * `node_modules/@aranova/tracking-react/dist/**`; this version sidesteps that
16
+ * class of bug entirely.
17
+ *
18
+ * For a fully bespoke banner, skip this component and use {@link useConsent}
19
+ * directly to drive your own UI.
20
+ *
21
+ * @example
22
+ * // Drop-in default
23
+ * <ConsentBanner />
24
+ *
25
+ * @example
26
+ * // Customized
27
+ * <ConsentBanner
28
+ * message="We use cookies to learn which ads drive bookings."
29
+ * acceptLabel="Sounds good"
30
+ * declineLabel="No thanks"
31
+ * policyHref="/privacy"
32
+ * policyLabel="Privacy policy"
33
+ * theme="dark"
34
+ * onAccept={() => track('consent_accepted')}
35
+ * onDecline={() => track('consent_declined')}
36
+ * />
37
+ */
38
+ interface ConsentBannerProps {
39
+ /** Body text. Defaults to the standard cookies-for-ad-performance message. */
40
+ message?: ReactNode;
41
+ /** Optional bold title above the body text. */
42
+ title?: ReactNode;
43
+ /** Label for the accept button. Default: `"Accept"`. */
44
+ acceptLabel?: string;
45
+ /** Label for the decline button. Default: `"Decline"`. */
46
+ declineLabel?: string;
47
+ /** Optional link inline with the message (e.g. to a privacy policy). */
48
+ policyHref?: string;
49
+ /** Visible text for {@link policyHref}. Default: `"Learn more"`. */
50
+ policyLabel?: string;
51
+ /**
52
+ * Fires after the consent state is persisted + propagated to gtag. Useful
53
+ * for emitting your own analytics event on the choice.
54
+ */
55
+ onAccept?: () => void;
56
+ onDecline?: () => void;
57
+ /** Where the banner docks. Default: `"bottom"`. */
58
+ position?: 'top' | 'bottom';
59
+ /**
60
+ * Visual theme. `"auto"` follows `prefers-color-scheme`. Default: `"light"`.
61
+ */
62
+ theme?: 'light' | 'dark' | 'auto';
63
+ /** Class added to the outer wrapper for additional styling hooks. */
64
+ className?: string;
65
+ /** Inline style overrides applied to the outer wrapper after the defaults. */
66
+ style?: CSSProperties;
67
+ }
68
+ declare function ConsentBanner({ message, title, acceptLabel, declineLabel, policyHref, policyLabel, onAccept, onDecline, position, theme, className, style, }?: ConsentBannerProps): ReactNode;
13
69
 
14
70
  /**
15
71
  * Visitor consent state stored by the SDK.
@@ -187,6 +243,22 @@ declare function getConsentState(): ConsentState;
187
243
  * loaded.
188
244
  */
189
245
  declare function setConsentState(state: GtagConsentValue): void;
246
+ /**
247
+ * Clear the stored consent choice so the banner re-appears on next render.
248
+ *
249
+ * Power a "Cookie preferences" link in a footer so visitors can change their
250
+ * mind without losing access to your site:
251
+ *
252
+ * ```tsx
253
+ * const { reset } = useConsent();
254
+ * <button onClick={reset}>Cookie preferences</button>
255
+ * ```
256
+ *
257
+ * Does NOT push an `update` to gtag — there's nothing to update because the
258
+ * visitor hasn't chosen anything yet. The next `setConsentState()` call will
259
+ * sync gtag once they re-choose.
260
+ */
261
+ declare function resetConsent(): void;
190
262
 
191
263
  interface TrackingContextInput {
192
264
  packageName?: string | null;
@@ -1781,8 +1853,46 @@ declare function useTrackingParams(): TrackingParams;
1781
1853
  /**
1782
1854
  * Read the current visitor consent state and update when another tab changes
1783
1855
  * the stored value.
1856
+ *
1857
+ * Prefer {@link useConsent} for new code — it returns the same state plus
1858
+ * the `accept` / `decline` / `reset` actions a custom consent UI needs.
1859
+ * `useConsentState` is kept as a convenience for callers that only need to
1860
+ * read.
1784
1861
  */
1785
1862
  declare function useConsentState(): ConsentState;
1863
+ /**
1864
+ * The headless consent surface — state + actions in one hook.
1865
+ *
1866
+ * Build a fully-custom banner without losing the gtag-sync, localStorage
1867
+ * persistence, or cross-tab propagation:
1868
+ *
1869
+ * ```tsx
1870
+ * const { state, accept, decline, reset, isPending } = useConsent();
1871
+ *
1872
+ * if (!isPending) {
1873
+ * return <button onClick={reset}>Cookie preferences</button>;
1874
+ * }
1875
+ * return (
1876
+ * <MyBannerStyling>
1877
+ * <button onClick={decline}>No thanks</button>
1878
+ * <button onClick={accept}>Sure</button>
1879
+ * </MyBannerStyling>
1880
+ * );
1881
+ * ```
1882
+ *
1883
+ * The boolean helpers (`isPending` / `isGranted` / `isDenied`) are equivalent
1884
+ * to comparing `state` directly — they're there for readability at call sites.
1885
+ */
1886
+ interface UseConsentResult {
1887
+ state: ConsentState;
1888
+ isPending: boolean;
1889
+ isGranted: boolean;
1890
+ isDenied: boolean;
1891
+ accept: () => void;
1892
+ decline: () => void;
1893
+ reset: () => void;
1894
+ }
1895
+ declare function useConsent(): UseConsentResult;
1786
1896
 
1787
1897
  interface CreateTrackingOptions<TRegistry extends TriggerRegistryConfig> {
1788
1898
  /**
@@ -1853,4 +1963,4 @@ interface CreateTrackingResult<TRegistry extends TriggerRegistryConfig> {
1853
1963
  }
1854
1964
  declare function createTracking<TRegistry extends TriggerRegistryConfig>(options: CreateTrackingOptions<TRegistry>): CreateTrackingResult<TRegistry>;
1855
1965
 
1856
- export { AranovaApiError, type AutomaticEventName, ConsentBanner, type ConsentState, type CreateTrackingOptions, type CreateTrackingResult, type CtaClickConfig, type CtaClickMetadata, type EventConfig, type EventMetadata, type EventName, type FormStartConfig, type FormStartMetadata, type FormSubmitConfig, type FormSubmitMetadata, GoogleAdsTracking, type GoogleAdsTrackingProps, type JsonValue, type ManualEventName, type MultiPageSessionConfig, type MultiPageSessionMetadata, type PageViewConfig, type PageViewMetadata, type PhoneClickConfig, type PhoneClickMetadata, type PublicServiceItem, type RegisteredAutomaticEvents, type RegisteredManualEvents, type Sale, type SaleCursorPage, type SaleInput, type SaleItem, type SaleItemInput, type SaleListPage, type SaleListQuery, type SaleUpdateInput, type SalesClient, type SalesClientConfig, type SalesTransportConfig, type ScrollDepthConfig, type ScrollDepthMetadata, type SpecificPageName, type SpecificPageVisitConfig, type SpecificPageVisitMetadata, type SupportedCurrency, TRACKING_PARAM_KEYS, type TimeOnSiteConfig, type TimeOnSiteMetadata, type TrackingClient, type TrackingClientContext, type TrackingEventCreatePayload, type TrackingInitConfig, type TrackingInstallSurface, type TrackingParams, type TrackingProviderProps, type TrackingSessionUpsertPayload, type TriggerRegistryConfig, type TypedTrackEventOptions, type TypedTrackingClient, captureTrackingParamsFromLocation, createSalesClient, createTracking, createTrackingClientContext, createTrackingEventCreatePayload, createTrackingSessionUpsertPayload, fetchServices, formatMoney, fromMinor, getConsentState, setConsentState, toMinor, useConsentState, useGclid, useTrackingParams };
1966
+ export { AranovaApiError, type AutomaticEventName, ConsentBanner, type ConsentBannerProps, type ConsentState, type CreateTrackingOptions, type CreateTrackingResult, type CtaClickConfig, type CtaClickMetadata, type EventConfig, type EventMetadata, type EventName, type FormStartConfig, type FormStartMetadata, type FormSubmitConfig, type FormSubmitMetadata, GoogleAdsTracking, type GoogleAdsTrackingProps, type JsonValue, type ManualEventName, type MultiPageSessionConfig, type MultiPageSessionMetadata, type PageViewConfig, type PageViewMetadata, type PhoneClickConfig, type PhoneClickMetadata, type PublicServiceItem, type RegisteredAutomaticEvents, type RegisteredManualEvents, type Sale, type SaleCursorPage, type SaleInput, type SaleItem, type SaleItemInput, type SaleListPage, type SaleListQuery, type SaleUpdateInput, type SalesClient, type SalesClientConfig, type SalesTransportConfig, type ScrollDepthConfig, type ScrollDepthMetadata, type SpecificPageName, type SpecificPageVisitConfig, type SpecificPageVisitMetadata, type SupportedCurrency, TRACKING_PARAM_KEYS, type TimeOnSiteConfig, type TimeOnSiteMetadata, type TrackingClient, type TrackingClientContext, type TrackingEventCreatePayload, type TrackingInitConfig, type TrackingInstallSurface, type TrackingParams, type TrackingProviderProps, type TrackingSessionUpsertPayload, type TriggerRegistryConfig, type TypedTrackEventOptions, type TypedTrackingClient, type UseConsentResult, captureTrackingParamsFromLocation, createSalesClient, createTracking, createTrackingClientContext, createTrackingEventCreatePayload, createTrackingSessionUpsertPayload, fetchServices, formatMoney, fromMinor, getConsentState, resetConsent, setConsentState, toMinor, useConsent, useConsentState, useGclid, useTrackingParams };
package/dist/index.d.ts CHANGED
@@ -1,15 +1,71 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode } from 'react';
1
+ import { ReactNode, CSSProperties } from 'react';
3
2
  import * as src from 'src';
4
3
  import { z } from 'zod';
5
4
 
6
5
  /**
7
6
  * Default non-blocking consent banner.
8
7
  *
9
- * Renders only while consent is `pending`. Accept/decline choices are stored
10
- * in localStorage and propagated to Google Consent Mode when gtag is loaded.
11
- */
12
- declare function ConsentBanner(): react_jsx_runtime.JSX.Element | null;
8
+ * Renders only while consent is `pending`; collapses to `null` once the
9
+ * visitor has chosen.
10
+ *
11
+ * **Styling is intentionally self-contained** — inline styles, zero CSS
12
+ * dependencies, no Tailwind required at the consumer. The Tailwind-based
13
+ * banner shipped before 0.9.1 rendered as transparent in any consumer that
14
+ * didn't configure their content array to scan
15
+ * `node_modules/@aranova/tracking-react/dist/**`; this version sidesteps that
16
+ * class of bug entirely.
17
+ *
18
+ * For a fully bespoke banner, skip this component and use {@link useConsent}
19
+ * directly to drive your own UI.
20
+ *
21
+ * @example
22
+ * // Drop-in default
23
+ * <ConsentBanner />
24
+ *
25
+ * @example
26
+ * // Customized
27
+ * <ConsentBanner
28
+ * message="We use cookies to learn which ads drive bookings."
29
+ * acceptLabel="Sounds good"
30
+ * declineLabel="No thanks"
31
+ * policyHref="/privacy"
32
+ * policyLabel="Privacy policy"
33
+ * theme="dark"
34
+ * onAccept={() => track('consent_accepted')}
35
+ * onDecline={() => track('consent_declined')}
36
+ * />
37
+ */
38
+ interface ConsentBannerProps {
39
+ /** Body text. Defaults to the standard cookies-for-ad-performance message. */
40
+ message?: ReactNode;
41
+ /** Optional bold title above the body text. */
42
+ title?: ReactNode;
43
+ /** Label for the accept button. Default: `"Accept"`. */
44
+ acceptLabel?: string;
45
+ /** Label for the decline button. Default: `"Decline"`. */
46
+ declineLabel?: string;
47
+ /** Optional link inline with the message (e.g. to a privacy policy). */
48
+ policyHref?: string;
49
+ /** Visible text for {@link policyHref}. Default: `"Learn more"`. */
50
+ policyLabel?: string;
51
+ /**
52
+ * Fires after the consent state is persisted + propagated to gtag. Useful
53
+ * for emitting your own analytics event on the choice.
54
+ */
55
+ onAccept?: () => void;
56
+ onDecline?: () => void;
57
+ /** Where the banner docks. Default: `"bottom"`. */
58
+ position?: 'top' | 'bottom';
59
+ /**
60
+ * Visual theme. `"auto"` follows `prefers-color-scheme`. Default: `"light"`.
61
+ */
62
+ theme?: 'light' | 'dark' | 'auto';
63
+ /** Class added to the outer wrapper for additional styling hooks. */
64
+ className?: string;
65
+ /** Inline style overrides applied to the outer wrapper after the defaults. */
66
+ style?: CSSProperties;
67
+ }
68
+ declare function ConsentBanner({ message, title, acceptLabel, declineLabel, policyHref, policyLabel, onAccept, onDecline, position, theme, className, style, }?: ConsentBannerProps): ReactNode;
13
69
 
14
70
  /**
15
71
  * Visitor consent state stored by the SDK.
@@ -187,6 +243,22 @@ declare function getConsentState(): ConsentState;
187
243
  * loaded.
188
244
  */
189
245
  declare function setConsentState(state: GtagConsentValue): void;
246
+ /**
247
+ * Clear the stored consent choice so the banner re-appears on next render.
248
+ *
249
+ * Power a "Cookie preferences" link in a footer so visitors can change their
250
+ * mind without losing access to your site:
251
+ *
252
+ * ```tsx
253
+ * const { reset } = useConsent();
254
+ * <button onClick={reset}>Cookie preferences</button>
255
+ * ```
256
+ *
257
+ * Does NOT push an `update` to gtag — there's nothing to update because the
258
+ * visitor hasn't chosen anything yet. The next `setConsentState()` call will
259
+ * sync gtag once they re-choose.
260
+ */
261
+ declare function resetConsent(): void;
190
262
 
191
263
  interface TrackingContextInput {
192
264
  packageName?: string | null;
@@ -1781,8 +1853,46 @@ declare function useTrackingParams(): TrackingParams;
1781
1853
  /**
1782
1854
  * Read the current visitor consent state and update when another tab changes
1783
1855
  * the stored value.
1856
+ *
1857
+ * Prefer {@link useConsent} for new code — it returns the same state plus
1858
+ * the `accept` / `decline` / `reset` actions a custom consent UI needs.
1859
+ * `useConsentState` is kept as a convenience for callers that only need to
1860
+ * read.
1784
1861
  */
1785
1862
  declare function useConsentState(): ConsentState;
1863
+ /**
1864
+ * The headless consent surface — state + actions in one hook.
1865
+ *
1866
+ * Build a fully-custom banner without losing the gtag-sync, localStorage
1867
+ * persistence, or cross-tab propagation:
1868
+ *
1869
+ * ```tsx
1870
+ * const { state, accept, decline, reset, isPending } = useConsent();
1871
+ *
1872
+ * if (!isPending) {
1873
+ * return <button onClick={reset}>Cookie preferences</button>;
1874
+ * }
1875
+ * return (
1876
+ * <MyBannerStyling>
1877
+ * <button onClick={decline}>No thanks</button>
1878
+ * <button onClick={accept}>Sure</button>
1879
+ * </MyBannerStyling>
1880
+ * );
1881
+ * ```
1882
+ *
1883
+ * The boolean helpers (`isPending` / `isGranted` / `isDenied`) are equivalent
1884
+ * to comparing `state` directly — they're there for readability at call sites.
1885
+ */
1886
+ interface UseConsentResult {
1887
+ state: ConsentState;
1888
+ isPending: boolean;
1889
+ isGranted: boolean;
1890
+ isDenied: boolean;
1891
+ accept: () => void;
1892
+ decline: () => void;
1893
+ reset: () => void;
1894
+ }
1895
+ declare function useConsent(): UseConsentResult;
1786
1896
 
1787
1897
  interface CreateTrackingOptions<TRegistry extends TriggerRegistryConfig> {
1788
1898
  /**
@@ -1853,4 +1963,4 @@ interface CreateTrackingResult<TRegistry extends TriggerRegistryConfig> {
1853
1963
  }
1854
1964
  declare function createTracking<TRegistry extends TriggerRegistryConfig>(options: CreateTrackingOptions<TRegistry>): CreateTrackingResult<TRegistry>;
1855
1965
 
1856
- export { AranovaApiError, type AutomaticEventName, ConsentBanner, type ConsentState, type CreateTrackingOptions, type CreateTrackingResult, type CtaClickConfig, type CtaClickMetadata, type EventConfig, type EventMetadata, type EventName, type FormStartConfig, type FormStartMetadata, type FormSubmitConfig, type FormSubmitMetadata, GoogleAdsTracking, type GoogleAdsTrackingProps, type JsonValue, type ManualEventName, type MultiPageSessionConfig, type MultiPageSessionMetadata, type PageViewConfig, type PageViewMetadata, type PhoneClickConfig, type PhoneClickMetadata, type PublicServiceItem, type RegisteredAutomaticEvents, type RegisteredManualEvents, type Sale, type SaleCursorPage, type SaleInput, type SaleItem, type SaleItemInput, type SaleListPage, type SaleListQuery, type SaleUpdateInput, type SalesClient, type SalesClientConfig, type SalesTransportConfig, type ScrollDepthConfig, type ScrollDepthMetadata, type SpecificPageName, type SpecificPageVisitConfig, type SpecificPageVisitMetadata, type SupportedCurrency, TRACKING_PARAM_KEYS, type TimeOnSiteConfig, type TimeOnSiteMetadata, type TrackingClient, type TrackingClientContext, type TrackingEventCreatePayload, type TrackingInitConfig, type TrackingInstallSurface, type TrackingParams, type TrackingProviderProps, type TrackingSessionUpsertPayload, type TriggerRegistryConfig, type TypedTrackEventOptions, type TypedTrackingClient, captureTrackingParamsFromLocation, createSalesClient, createTracking, createTrackingClientContext, createTrackingEventCreatePayload, createTrackingSessionUpsertPayload, fetchServices, formatMoney, fromMinor, getConsentState, setConsentState, toMinor, useConsentState, useGclid, useTrackingParams };
1966
+ export { AranovaApiError, type AutomaticEventName, ConsentBanner, type ConsentBannerProps, type ConsentState, type CreateTrackingOptions, type CreateTrackingResult, type CtaClickConfig, type CtaClickMetadata, type EventConfig, type EventMetadata, type EventName, type FormStartConfig, type FormStartMetadata, type FormSubmitConfig, type FormSubmitMetadata, GoogleAdsTracking, type GoogleAdsTrackingProps, type JsonValue, type ManualEventName, type MultiPageSessionConfig, type MultiPageSessionMetadata, type PageViewConfig, type PageViewMetadata, type PhoneClickConfig, type PhoneClickMetadata, type PublicServiceItem, type RegisteredAutomaticEvents, type RegisteredManualEvents, type Sale, type SaleCursorPage, type SaleInput, type SaleItem, type SaleItemInput, type SaleListPage, type SaleListQuery, type SaleUpdateInput, type SalesClient, type SalesClientConfig, type SalesTransportConfig, type ScrollDepthConfig, type ScrollDepthMetadata, type SpecificPageName, type SpecificPageVisitConfig, type SpecificPageVisitMetadata, type SupportedCurrency, TRACKING_PARAM_KEYS, type TimeOnSiteConfig, type TimeOnSiteMetadata, type TrackingClient, type TrackingClientContext, type TrackingEventCreatePayload, type TrackingInitConfig, type TrackingInstallSurface, type TrackingParams, type TrackingProviderProps, type TrackingSessionUpsertPayload, type TriggerRegistryConfig, type TypedTrackEventOptions, type TypedTrackingClient, type UseConsentResult, captureTrackingParamsFromLocation, createSalesClient, createTracking, createTrackingClientContext, createTrackingEventCreatePayload, createTrackingSessionUpsertPayload, fetchServices, formatMoney, fromMinor, getConsentState, resetConsent, setConsentState, toMinor, useConsent, useConsentState, useGclid, useTrackingParams };