@aranova/tracking-react 0.14.0 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -3
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +58 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +58 -17
- package/dist/index.mjs.map +1 -1
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs.map +1 -1
- package/dist/{sales-BsJodmh0.d.mts → sales-Bq7H-Vym.d.mts} +14 -5
- package/dist/{sales-BsJodmh0.d.ts → sales-Bq7H-Vym.d.ts} +14 -5
- package/dist/sales.d.mts +1 -1
- package/dist/sales.d.ts +1 -1
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -223,8 +223,10 @@ export const { TrackingProvider, useTracking } = createTracking({
|
|
|
223
223
|
|
|
224
224
|
```ts
|
|
225
225
|
import { createSalesClient, resolveConversionConfig, toMinor } from "@aranova/tracking-react";
|
|
226
|
+
import type { AranovaService, AranovaConversion } from "./aranova-services"; // generated by `gen`
|
|
226
227
|
|
|
227
|
-
|
|
228
|
+
// Bind the generated unions so `service` and `trackConversion` keys are type-checked.
|
|
229
|
+
const sales = createSalesClient<AranovaService, AranovaConversion>({
|
|
228
230
|
apiKey,
|
|
229
231
|
endpoint,
|
|
230
232
|
firing: resolveConversionConfig({ cdnUrl: ARANOVA_CONFIG_URL }),
|
|
@@ -235,10 +237,23 @@ await sales.recordSale({
|
|
|
235
237
|
amount_total_cents: toMinor(250, "CAD"),
|
|
236
238
|
service: "tires",
|
|
237
239
|
}); // records + fires
|
|
238
|
-
sales.trackConversion("phone_click"); // fires a manual event-goal only (no sale recorded)
|
|
239
240
|
```
|
|
240
241
|
|
|
241
|
-
|
|
242
|
+
**Manual conversions (multiple forms):** register the trigger once, then call `trackConversion(key)` in each form's submit handler. Keys come from the dashboard Goals tab (event-goals with a `form_submit`/`phone_click`/`cta_click` trigger mapped to a WEBPAGE action) and are emitted as the `AranovaConversion` union by `gen` — so they autocomplete and reject typos:
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
// createTracking({ …, triggers: { manual: { form_submit: {} } } }) // register once
|
|
246
|
+
|
|
247
|
+
// in the contact form's onSubmit:
|
|
248
|
+
sales.trackConversion("contact_form"); // ✅ typed by AranovaConversion
|
|
249
|
+
// in the demo form's onSubmit:
|
|
250
|
+
sales.trackConversion("demo_request");
|
|
251
|
+
sales.trackConversion("typo"); // ❌ compile error — not a known goal key
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Each call fires **only** the WEBPAGE conversion for that goal (no `/sales` write); the SDK no-ops if the goal isn't mapped. Firing is consent-gated, de-duped by `transaction_id`, and no-ops server-side. The config bucket needs an R2 CORS policy — see [conversion-config-schema.md](https://github.com/AranovaIO/aranova_internal/blob/master/docs/tracking-package/conversion-config-schema.md).
|
|
255
|
+
|
|
256
|
+
> **Before any manual goal exists,** `gen` emits an empty `ARANOVA_CONVERSIONS`, so `AranovaConversion` resolves to `never` — binding it (`createSalesClient<AranovaService, AranovaConversion>`) then makes **every** `trackConversion` call a compile error. Until you've mapped at least one manual goal and re-run `gen`, bind only the service generic (`createSalesClient<AranovaService>(…)`); the conversion key defaults back to `string`.
|
|
242
257
|
|
|
243
258
|
## Consent UI
|
|
244
259
|
|
package/dist/index.d.mts
CHANGED
|
@@ -2,8 +2,8 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode, CSSProperties, InputHTMLAttributes, ChangeEvent, FocusEvent } from 'react';
|
|
3
3
|
import { C as ConsentState, T as TrackingInstallSurface, a as TrackingEnvironment, b as TrackingClientContext, c as TrackingParams, d as TrackingEventCreatePayload, e as TrackingSessionUpsertPayload, F as FormSubmitConfig, f as FormSubmitMetadata, G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, P as PhoneConfig, g as ParsedPhone, h as PhoneDisplayFormat } from './phone-utils-Dyk0F14_.mjs';
|
|
4
4
|
export { D as DEFAULT_PHONE_COUNTRY, J as JsonValue, i as TrackedField, j as TrackingInitConfig, k as formSubmitConfigSchema, l as formSubmitMetadataSchema, m as formatPhone, n as formatPhoneAsTyped, o as jsonValueSchema, p as parsePhone, q as phoneField, t as toE164 } from './phone-utils-Dyk0F14_.mjs';
|
|
5
|
-
import { C as ConversionConfig } from './sales-
|
|
6
|
-
export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, c as CompareTo, d as ConversionConfigStore, e as CurrencyRevenue, f as CustomerCurrencyDelta, g as CustomerCurrencyTotal, h as CustomerGetOptions, i as CustomerGetResult, j as CustomerKpis, k as CustomerKpisDeltas, l as CustomerKpisPrevious, m as CustomerListPage, n as CustomerListQuery, o as CustomerProfile, p as CustomerSegment, q as CustomerSegmentCount, r as CustomerSortField, s as CustomerSummary, t as CustomerSummaryQuery, D as DistinctCustomersByCurrency, G as Granularity, N as NAMED_RANGES, u as NamedRange, P as PublicServiceItem, S as SUPPORTED_CURRENCIES, v as Sale, w as SaleCursorPage, x as SaleFilters, y as SaleInput, z as SaleItem, E as SaleItemInput, F as SaleKeysetSortField, H as SaleListPage, I as SaleListQuery, J as SaleListQueryV2, K as SaleService, L as SaleServiceInput, M as SaleSortField, O as SaleSortOrder, Q as SaleSummary, R as SaleSummaryPrevious, T as SaleSummaryQuery, U as SaleSummaryQueryV2, V as SaleSummaryV2, W as SaleUpdateInput, X as SalesBusinessClient, Y as SalesCategoryBreakdown, Z as SalesClient, _ as SalesClientConfig, $ as SalesCustomersClient, a0 as SalesServiceBreakdown, a1 as SalesTransportConfig, a2 as SalesTrendPoint, a3 as SummaryCurrencyDelta, a4 as SummaryDeltas, a5 as SummaryWindow, a6 as SupportedCurrency, a7 as TRACKING_RANGES, a8 as TrackingOverviewRange, a9 as createSalesClient, aa as fetchServices, ab as formatDateInTz, ac as formatMoney, ad as fromMinor, ae as resolveConversionConfig, af as saleCreateSchema, ag as saleItemSchema, ah as saleServiceSchema, ai as saleUpdateSchema, aj as salesRequest, ak as toMinor } from './sales-
|
|
5
|
+
import { C as ConversionConfig } from './sales-Bq7H-Vym.mjs';
|
|
6
|
+
export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, c as CompareTo, d as ConversionConfigStore, e as CurrencyRevenue, f as CustomerCurrencyDelta, g as CustomerCurrencyTotal, h as CustomerGetOptions, i as CustomerGetResult, j as CustomerKpis, k as CustomerKpisDeltas, l as CustomerKpisPrevious, m as CustomerListPage, n as CustomerListQuery, o as CustomerProfile, p as CustomerSegment, q as CustomerSegmentCount, r as CustomerSortField, s as CustomerSummary, t as CustomerSummaryQuery, D as DistinctCustomersByCurrency, G as Granularity, N as NAMED_RANGES, u as NamedRange, P as PublicServiceItem, S as SUPPORTED_CURRENCIES, v as Sale, w as SaleCursorPage, x as SaleFilters, y as SaleInput, z as SaleItem, E as SaleItemInput, F as SaleKeysetSortField, H as SaleListPage, I as SaleListQuery, J as SaleListQueryV2, K as SaleService, L as SaleServiceInput, M as SaleSortField, O as SaleSortOrder, Q as SaleSummary, R as SaleSummaryPrevious, T as SaleSummaryQuery, U as SaleSummaryQueryV2, V as SaleSummaryV2, W as SaleUpdateInput, X as SalesBusinessClient, Y as SalesCategoryBreakdown, Z as SalesClient, _ as SalesClientConfig, $ as SalesCustomersClient, a0 as SalesServiceBreakdown, a1 as SalesTransportConfig, a2 as SalesTrendPoint, a3 as SummaryCurrencyDelta, a4 as SummaryDeltas, a5 as SummaryWindow, a6 as SupportedCurrency, a7 as TRACKING_RANGES, a8 as TrackingOverviewRange, a9 as createSalesClient, aa as fetchServices, ab as formatDateInTz, ac as formatMoney, ad as fromMinor, ae as resolveConversionConfig, af as saleCreateSchema, ag as saleItemSchema, ah as saleServiceSchema, ai as saleUpdateSchema, aj as salesRequest, ak as toMinor } from './sales-Bq7H-Vym.mjs';
|
|
7
7
|
import * as src from 'src';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import { CountryCode } from 'libphonenumber-js';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode, CSSProperties, InputHTMLAttributes, ChangeEvent, FocusEvent } from 'react';
|
|
3
3
|
import { C as ConsentState, T as TrackingInstallSurface, a as TrackingEnvironment, b as TrackingClientContext, c as TrackingParams, d as TrackingEventCreatePayload, e as TrackingSessionUpsertPayload, F as FormSubmitConfig, f as FormSubmitMetadata, G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, P as PhoneConfig, g as ParsedPhone, h as PhoneDisplayFormat } from './phone-utils-Dyk0F14_.js';
|
|
4
4
|
export { D as DEFAULT_PHONE_COUNTRY, J as JsonValue, i as TrackedField, j as TrackingInitConfig, k as formSubmitConfigSchema, l as formSubmitMetadataSchema, m as formatPhone, n as formatPhoneAsTyped, o as jsonValueSchema, p as parsePhone, q as phoneField, t as toE164 } from './phone-utils-Dyk0F14_.js';
|
|
5
|
-
import { C as ConversionConfig } from './sales-
|
|
6
|
-
export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, c as CompareTo, d as ConversionConfigStore, e as CurrencyRevenue, f as CustomerCurrencyDelta, g as CustomerCurrencyTotal, h as CustomerGetOptions, i as CustomerGetResult, j as CustomerKpis, k as CustomerKpisDeltas, l as CustomerKpisPrevious, m as CustomerListPage, n as CustomerListQuery, o as CustomerProfile, p as CustomerSegment, q as CustomerSegmentCount, r as CustomerSortField, s as CustomerSummary, t as CustomerSummaryQuery, D as DistinctCustomersByCurrency, G as Granularity, N as NAMED_RANGES, u as NamedRange, P as PublicServiceItem, S as SUPPORTED_CURRENCIES, v as Sale, w as SaleCursorPage, x as SaleFilters, y as SaleInput, z as SaleItem, E as SaleItemInput, F as SaleKeysetSortField, H as SaleListPage, I as SaleListQuery, J as SaleListQueryV2, K as SaleService, L as SaleServiceInput, M as SaleSortField, O as SaleSortOrder, Q as SaleSummary, R as SaleSummaryPrevious, T as SaleSummaryQuery, U as SaleSummaryQueryV2, V as SaleSummaryV2, W as SaleUpdateInput, X as SalesBusinessClient, Y as SalesCategoryBreakdown, Z as SalesClient, _ as SalesClientConfig, $ as SalesCustomersClient, a0 as SalesServiceBreakdown, a1 as SalesTransportConfig, a2 as SalesTrendPoint, a3 as SummaryCurrencyDelta, a4 as SummaryDeltas, a5 as SummaryWindow, a6 as SupportedCurrency, a7 as TRACKING_RANGES, a8 as TrackingOverviewRange, a9 as createSalesClient, aa as fetchServices, ab as formatDateInTz, ac as formatMoney, ad as fromMinor, ae as resolveConversionConfig, af as saleCreateSchema, ag as saleItemSchema, ah as saleServiceSchema, ai as saleUpdateSchema, aj as salesRequest, ak as toMinor } from './sales-
|
|
5
|
+
import { C as ConversionConfig } from './sales-Bq7H-Vym.js';
|
|
6
|
+
export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, c as CompareTo, d as ConversionConfigStore, e as CurrencyRevenue, f as CustomerCurrencyDelta, g as CustomerCurrencyTotal, h as CustomerGetOptions, i as CustomerGetResult, j as CustomerKpis, k as CustomerKpisDeltas, l as CustomerKpisPrevious, m as CustomerListPage, n as CustomerListQuery, o as CustomerProfile, p as CustomerSegment, q as CustomerSegmentCount, r as CustomerSortField, s as CustomerSummary, t as CustomerSummaryQuery, D as DistinctCustomersByCurrency, G as Granularity, N as NAMED_RANGES, u as NamedRange, P as PublicServiceItem, S as SUPPORTED_CURRENCIES, v as Sale, w as SaleCursorPage, x as SaleFilters, y as SaleInput, z as SaleItem, E as SaleItemInput, F as SaleKeysetSortField, H as SaleListPage, I as SaleListQuery, J as SaleListQueryV2, K as SaleService, L as SaleServiceInput, M as SaleSortField, O as SaleSortOrder, Q as SaleSummary, R as SaleSummaryPrevious, T as SaleSummaryQuery, U as SaleSummaryQueryV2, V as SaleSummaryV2, W as SaleUpdateInput, X as SalesBusinessClient, Y as SalesCategoryBreakdown, Z as SalesClient, _ as SalesClientConfig, $ as SalesCustomersClient, a0 as SalesServiceBreakdown, a1 as SalesTransportConfig, a2 as SalesTrendPoint, a3 as SummaryCurrencyDelta, a4 as SummaryDeltas, a5 as SummaryWindow, a6 as SupportedCurrency, a7 as TRACKING_RANGES, a8 as TrackingOverviewRange, a9 as createSalesClient, aa as fetchServices, ab as formatDateInTz, ac as formatMoney, ad as fromMinor, ae as resolveConversionConfig, af as saleCreateSchema, ag as saleItemSchema, ah as saleServiceSchema, ai as saleUpdateSchema, aj as salesRequest, ak as toMinor } from './sales-Bq7H-Vym.js';
|
|
7
7
|
import * as src from 'src';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import { CountryCode } from 'libphonenumber-js';
|
package/dist/index.js
CHANGED
|
@@ -246,9 +246,10 @@ function isValidGtagId(id) {
|
|
|
246
246
|
function ensureGtagFunction() {
|
|
247
247
|
window.dataLayer = window.dataLayer || [];
|
|
248
248
|
if (typeof window.gtag === "function") return window.gtag;
|
|
249
|
-
|
|
250
|
-
window.dataLayer?.push(
|
|
251
|
-
}
|
|
249
|
+
function gtag() {
|
|
250
|
+
window.dataLayer?.push(arguments);
|
|
251
|
+
}
|
|
252
|
+
window.gtag = gtag;
|
|
252
253
|
return window.gtag;
|
|
253
254
|
}
|
|
254
255
|
var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
|
|
@@ -626,19 +627,32 @@ function resolveConversionConfig(options) {
|
|
|
626
627
|
let current = cached?.config ?? options.baked ?? null;
|
|
627
628
|
let etag = cached?.etag ?? null;
|
|
628
629
|
const goalsByKey = /* @__PURE__ */ new Map();
|
|
630
|
+
const resolveListeners = /* @__PURE__ */ new Set();
|
|
629
631
|
function rebuildIndex() {
|
|
630
632
|
goalsByKey.clear();
|
|
631
633
|
for (const goal of current?.goals ?? []) {
|
|
632
634
|
goalsByKey.set(goal.key, goal);
|
|
633
635
|
}
|
|
634
636
|
}
|
|
637
|
+
function notifyResolved() {
|
|
638
|
+
const listeners = [...resolveListeners];
|
|
639
|
+
resolveListeners.clear();
|
|
640
|
+
for (const listener of listeners) {
|
|
641
|
+
try {
|
|
642
|
+
listener();
|
|
643
|
+
} catch {
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
635
647
|
function adopt(next, nextEtag) {
|
|
636
648
|
if (!next) return;
|
|
637
649
|
if (current && next.config_version <= current.config_version) return;
|
|
650
|
+
const wasEmpty = current === null;
|
|
638
651
|
current = next;
|
|
639
652
|
etag = nextEtag;
|
|
640
653
|
rebuildIndex();
|
|
641
654
|
writeCache(options.cdnUrl, { etag, config: next });
|
|
655
|
+
if (wasEmpty) notifyResolved();
|
|
642
656
|
}
|
|
643
657
|
async function revalidate() {
|
|
644
658
|
if (typeof window === "undefined") return;
|
|
@@ -663,6 +677,16 @@ function resolveConversionConfig(options) {
|
|
|
663
677
|
getGoal: (key) => goalsByKey.get(key) ?? null,
|
|
664
678
|
listGoals: () => [...goalsByKey.values()],
|
|
665
679
|
current: () => current,
|
|
680
|
+
isReady: () => current !== null,
|
|
681
|
+
onResolve: (listener) => {
|
|
682
|
+
if (current !== null) {
|
|
683
|
+
listener();
|
|
684
|
+
return () => {
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
resolveListeners.add(listener);
|
|
688
|
+
return () => resolveListeners.delete(listener);
|
|
689
|
+
},
|
|
666
690
|
revalidate
|
|
667
691
|
};
|
|
668
692
|
}
|
|
@@ -724,22 +748,39 @@ function thresholdMet(goal, eventType, metadata) {
|
|
|
724
748
|
function currentPath() {
|
|
725
749
|
return typeof window === "undefined" ? "" : window.location.pathname;
|
|
726
750
|
}
|
|
751
|
+
var MAX_BUFFERED_EVENTS = 50;
|
|
727
752
|
function createConversionAutoFire(store) {
|
|
753
|
+
const pending = [];
|
|
754
|
+
let subscribed = false;
|
|
755
|
+
function fireMatching(eventType, metadata) {
|
|
756
|
+
for (const goal of store.listGoals()) {
|
|
757
|
+
if (goal.kind !== "event" || !goal.firing) continue;
|
|
758
|
+
if (!thresholdMet(goal, eventType, metadata)) continue;
|
|
759
|
+
const firing = goal.firing;
|
|
760
|
+
const cents = firing.value_cents ?? null;
|
|
761
|
+
const currency = firing.currency ?? null;
|
|
762
|
+
fireConversionWithConsent({
|
|
763
|
+
sendTo: firing.send_to,
|
|
764
|
+
value: cents != null && currency ? fromMinor(cents, currency) : null,
|
|
765
|
+
currency,
|
|
766
|
+
// Page-scoped txn id → fire once per (goal, path) per session; engagement conversions
|
|
767
|
+
// shouldn't re-fire as the visitor scrolls back and forth or re-enters a page.
|
|
768
|
+
transactionId: `auto:${goal.key}:${currentPath()}`
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
}
|
|
728
772
|
return {
|
|
729
773
|
onAutomaticEvent(eventType, metadata) {
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
// Page-scoped txn id → fire once per (goal, path) per session; engagement conversions
|
|
741
|
-
// shouldn't re-fire as the visitor scrolls back and forth or re-enters a page.
|
|
742
|
-
transactionId: `auto:${goal.key}:${currentPath()}`
|
|
774
|
+
if (store.isReady()) {
|
|
775
|
+
fireMatching(eventType, metadata);
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
if (pending.length < MAX_BUFFERED_EVENTS) pending.push({ eventType, metadata });
|
|
779
|
+
if (!subscribed) {
|
|
780
|
+
subscribed = true;
|
|
781
|
+
store.onResolve(() => {
|
|
782
|
+
const buffered = pending.splice(0);
|
|
783
|
+
for (const event of buffered) fireMatching(event.eventType, event.metadata);
|
|
743
784
|
});
|
|
744
785
|
}
|
|
745
786
|
}
|
|
@@ -2449,7 +2490,7 @@ function GoogleAdsTracking(props) {
|
|
|
2449
2490
|
var import_react6 = require("react");
|
|
2450
2491
|
|
|
2451
2492
|
// package.json
|
|
2452
|
-
var version = "0.14.
|
|
2493
|
+
var version = "0.14.2";
|
|
2453
2494
|
|
|
2454
2495
|
// ../tracking-core/src/phone-react.tsx
|
|
2455
2496
|
var import_react5 = require("react");
|