@aranova/tracking-react 1.2.2 → 1.2.3

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/dist/client.mjs CHANGED
@@ -1701,6 +1701,12 @@ var EVENT_SEMANTICS = {
1701
1701
  outcomeRole: "diagnostic",
1702
1702
  clientVisibility: "detailed"
1703
1703
  },
1704
+ form_step: {
1705
+ label: "Form step",
1706
+ category: "engagement",
1707
+ outcomeRole: "engagement",
1708
+ clientVisibility: "detailed"
1709
+ },
1704
1710
  form_submit: {
1705
1711
  label: "Form submitted",
1706
1712
  category: "lead",
@@ -2364,7 +2370,7 @@ function createTrackingClient(config) {
2364
2370
  }
2365
2371
 
2366
2372
  // ../tracking-core/src/ingest-typed.ts
2367
- import { parse as parse2 } from "zod/mini";
2373
+ import { parse as parse2, safeParse } from "zod/mini";
2368
2374
 
2369
2375
  // ../tracking-core/src/events/cta-click.ts
2370
2376
  import * as z3 from "zod/mini";
@@ -2421,58 +2427,79 @@ var formStartConfigSchema = z5.strictObject({
2421
2427
  selector: z5.optional(z5.string())
2422
2428
  });
2423
2429
 
2424
- // ../tracking-core/src/events/form-submit.ts
2430
+ // ../tracking-core/src/events/form-step.ts
2425
2431
  import * as z6 from "zod/mini";
2426
- var jsonValueSchema = z6.lazy(
2427
- () => z6.union([
2428
- z6.string(),
2429
- z6.number(),
2430
- z6.boolean(),
2431
- z6.null(),
2432
- z6.array(jsonValueSchema),
2433
- z6.record(z6.string(), jsonValueSchema)
2434
- ])
2435
- ).register(z6.globalRegistry, { id: "JsonSerializableValue" });
2436
- var formSubmitMetadataSchema = z6.strictObject({
2432
+ var formStepMetadataSchema = z6.strictObject({
2437
2433
  form: z6.strictObject({
2438
2434
  id: z6.string(),
2439
- action: z6.nullable(z6.string()),
2440
- fields: z6.optional(
2441
- z6.array(
2442
- z6.strictObject({
2443
- name: z6.string(),
2444
- type: z6.string(),
2445
- label: z6.nullable(z6.string()),
2446
- value: jsonValueSchema
2447
- })
2448
- )
2449
- )
2435
+ action: z6.nullable(z6.string())
2436
+ }),
2437
+ step: z6.strictObject({
2438
+ id: z6.string().check(z6.minLength(1), z6.maxLength(64), z6.regex(/^[A-Za-z0-9_-]+$/)),
2439
+ // 1-based position in the flow the visitor is on right now.
2440
+ index: z6.int().check(z6.gte(1), z6.lte(50)),
2441
+ // Null when the number of steps depends on earlier answers.
2442
+ total: z6.nullable(z6.int().check(z6.gte(1), z6.lte(50)))
2450
2443
  }),
2444
+ direction: z6.enum(["forward", "back"]),
2451
2445
  page: z6.strictObject({
2452
2446
  path: z6.string()
2453
2447
  })
2454
2448
  });
2455
- var formSubmitConfigSchema = z6.strictObject({});
2449
+ var formStepConfigSchema = z6.strictObject({});
2456
2450
 
2457
- // ../tracking-core/src/events/multi-page-session.ts
2451
+ // ../tracking-core/src/events/form-submit.ts
2458
2452
  import * as z7 from "zod/mini";
2459
- var multiPageSessionMetadataSchema = z7.strictObject({
2460
- page_count: z7.int().check(z7.gte(2)),
2453
+ var jsonValueSchema = z7.lazy(
2454
+ () => z7.union([
2455
+ z7.string(),
2456
+ z7.number(),
2457
+ z7.boolean(),
2458
+ z7.null(),
2459
+ z7.array(jsonValueSchema),
2460
+ z7.record(z7.string(), jsonValueSchema)
2461
+ ])
2462
+ ).register(z7.globalRegistry, { id: "JsonSerializableValue" });
2463
+ var formSubmitMetadataSchema = z7.strictObject({
2464
+ form: z7.strictObject({
2465
+ id: z7.string(),
2466
+ action: z7.nullable(z7.string()),
2467
+ fields: z7.optional(
2468
+ z7.array(
2469
+ z7.strictObject({
2470
+ name: z7.string(),
2471
+ type: z7.string(),
2472
+ label: z7.nullable(z7.string()),
2473
+ value: jsonValueSchema
2474
+ })
2475
+ )
2476
+ )
2477
+ }),
2461
2478
  page: z7.strictObject({
2462
2479
  path: z7.string()
2463
2480
  })
2464
2481
  });
2465
- var multiPageSessionConfigSchema = z7.strictObject({
2466
- pageThreshold: z7.int().check(z7.gte(2))
2482
+ var formSubmitConfigSchema = z7.strictObject({});
2483
+
2484
+ // ../tracking-core/src/events/multi-page-session.ts
2485
+ import * as z8 from "zod/mini";
2486
+ var multiPageSessionMetadataSchema = z8.strictObject({
2487
+ page_count: z8.int().check(z8.gte(2)),
2488
+ page: z8.strictObject({
2489
+ path: z8.string()
2490
+ })
2491
+ });
2492
+ var multiPageSessionConfigSchema = z8.strictObject({
2493
+ pageThreshold: z8.int().check(z8.gte(2))
2467
2494
  });
2468
2495
 
2469
2496
  // ../tracking-core/src/events/page-exit.ts
2470
- import * as z8 from "zod/mini";
2471
- var pageExitMetadataSchema = z8.strictObject({
2472
- dwell_ms: z8.int().check(z8.gte(0)),
2497
+ import * as z9 from "zod/mini";
2498
+ var pageExitMetadataSchema = z9.strictObject({
2499
+ dwell_ms: z9.int().check(z9.gte(0)),
2473
2500
  // null = left without any scroll signal; floor is 0 so a valid 0% is never
2474
2501
  // rejected (a single bad field 422s the whole keepalive beacon batch).
2475
- max_scroll_percent: z8.nullable(z8.int().check(z8.gte(0), z8.lte(100))),
2502
+ max_scroll_percent: z9.nullable(z9.int().check(z9.gte(0), z9.lte(100))),
2476
2503
  // The gating baseline: the fraction of the page visible at load with
2477
2504
  // zero scrolling — or, for pages that grew after the post-paint snapshot
2478
2505
  // (skeleton/streaming renders), the first-scroll position that
@@ -2480,104 +2507,104 @@ var pageExitMetadataSchema = z8.strictObject({
2480
2507
  // ended before the snapshot. Optionality is load-bearing: SDK builds
2481
2508
  // predating this field keep POSTing page_exit without the key —
2482
2509
  // requiring it would 422 whole keepalive beacon batches.
2483
- scroll_baseline_percent: z8.optional(z8.nullable(z8.int().check(z8.gte(0), z8.lte(100)))),
2484
- page: z8.strictObject({
2485
- path: z8.string()
2510
+ scroll_baseline_percent: z9.optional(z9.nullable(z9.int().check(z9.gte(0), z9.lte(100)))),
2511
+ page: z9.strictObject({
2512
+ path: z9.string()
2486
2513
  })
2487
2514
  });
2488
- var pageExitConfigSchema = z8.strictObject({});
2515
+ var pageExitConfigSchema = z9.strictObject({});
2489
2516
 
2490
2517
  // ../tracking-core/src/events/phone-click.ts
2491
- import * as z9 from "zod/mini";
2492
- var phoneClickMetadataSchema = z9.strictObject({
2493
- phone_number: z9.string(),
2494
- page: z9.strictObject({
2495
- path: z9.string()
2518
+ import * as z10 from "zod/mini";
2519
+ var phoneClickMetadataSchema = z10.strictObject({
2520
+ phone_number: z10.string(),
2521
+ page: z10.strictObject({
2522
+ path: z10.string()
2496
2523
  }),
2497
- section: z9.optional(z9.nullable(z9.string()))
2524
+ section: z10.optional(z10.nullable(z10.string()))
2498
2525
  });
2499
- var phoneClickConfigSchema = z9.strictObject({
2500
- autoCapture: z9.optional(
2501
- z9.strictObject({
2502
- selector: z9.optional(z9.string())
2526
+ var phoneClickConfigSchema = z10.strictObject({
2527
+ autoCapture: z10.optional(
2528
+ z10.strictObject({
2529
+ selector: z10.optional(z10.string())
2503
2530
  })
2504
2531
  )
2505
2532
  });
2506
2533
 
2507
2534
  // ../tracking-core/src/events/scroll-depth.ts
2508
- import * as z10 from "zod/mini";
2509
- var scrollDepthMetadataSchema = z10.strictObject({
2510
- depth_percent: z10.int().check(z10.gte(1), z10.lte(100)),
2511
- page: z10.strictObject({
2512
- path: z10.string()
2535
+ import * as z11 from "zod/mini";
2536
+ var scrollDepthMetadataSchema = z11.strictObject({
2537
+ depth_percent: z11.int().check(z11.gte(1), z11.lte(100)),
2538
+ page: z11.strictObject({
2539
+ path: z11.string()
2513
2540
  })
2514
2541
  });
2515
- var scrollDepthConfigSchema = z10.strictObject({
2516
- thresholds: z10.array(z10.int().check(z10.gte(1), z10.lte(100))).check(z10.minLength(1))
2542
+ var scrollDepthConfigSchema = z11.strictObject({
2543
+ thresholds: z11.array(z11.int().check(z11.gte(1), z11.lte(100))).check(z11.minLength(1))
2517
2544
  });
2518
2545
 
2519
2546
  // ../tracking-core/src/events/specific-page-visit.ts
2520
- import * as z11 from "zod/mini";
2547
+ import * as z12 from "zod/mini";
2521
2548
  var PAGE_IDENTITY_MAX_LENGTH = 64;
2522
2549
  var PAGE_IDENTITY_PATTERN = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/;
2523
- var pageIdentitySchema = z11.string().check(
2524
- z11.maxLength(PAGE_IDENTITY_MAX_LENGTH),
2525
- z11.regex(PAGE_IDENTITY_PATTERN, {
2550
+ var pageIdentitySchema = z12.string().check(
2551
+ z12.maxLength(PAGE_IDENTITY_MAX_LENGTH),
2552
+ z12.regex(PAGE_IDENTITY_PATTERN, {
2526
2553
  message: "page identity must be lowercase snake_case, start with a letter, and contain at most 64 characters"
2527
2554
  })
2528
2555
  );
2529
2556
  var specificPageNameSchema = pageIdentitySchema;
2530
- var specificPageVisitMetadataSchema = z11.strictObject({
2557
+ var specificPageVisitMetadataSchema = z12.strictObject({
2531
2558
  page_name: specificPageNameSchema,
2532
- page: z11.strictObject({
2533
- path: z11.string()
2559
+ page: z12.strictObject({
2560
+ path: z12.string()
2534
2561
  })
2535
2562
  });
2536
- var specificPageVisitConfigSchema = z11.strictObject({
2537
- pages: z11.array(
2538
- z11.strictObject({
2563
+ var specificPageVisitConfigSchema = z12.strictObject({
2564
+ pages: z12.array(
2565
+ z12.strictObject({
2539
2566
  name: specificPageNameSchema,
2540
- pathPattern: z11.custom((value) => value instanceof RegExp, {
2567
+ pathPattern: z12.custom((value) => value instanceof RegExp, {
2541
2568
  message: "pathPattern must be a RegExp"
2542
2569
  })
2543
2570
  })
2544
- ).check(z11.minLength(1))
2571
+ ).check(z12.minLength(1))
2545
2572
  });
2546
2573
 
2547
2574
  // ../tracking-core/src/events/site-link.ts
2548
- import * as z12 from "zod/mini";
2549
- var siteLinkClickMetadataSchema = z12.strictObject({
2550
- destination_host: z12.string(),
2551
- destination_url: z12.string(),
2552
- page: z12.strictObject({
2553
- path: z12.string()
2575
+ import * as z13 from "zod/mini";
2576
+ var siteLinkClickMetadataSchema = z13.strictObject({
2577
+ destination_host: z13.string(),
2578
+ destination_url: z13.string(),
2579
+ page: z13.strictObject({
2580
+ path: z13.string()
2554
2581
  })
2555
2582
  });
2556
- var siteLinkClickConfigSchema = z12.strictObject({});
2557
- var siteLinkArrivalMetadataSchema = z12.strictObject({
2558
- outcome: z12.enum(["linked", "stale", "invalid"]),
2559
- origin_session_id: z12.optional(z12.nullable(z12.string())),
2560
- origin_visitor_id: z12.optional(z12.nullable(z12.string())),
2583
+ var siteLinkClickConfigSchema = z13.strictObject({});
2584
+ var siteLinkArrivalMetadataSchema = z13.strictObject({
2585
+ outcome: z13.enum(["linked", "stale", "invalid"]),
2586
+ origin_session_id: z13.optional(z13.nullable(z13.string())),
2587
+ origin_visitor_id: z13.optional(z13.nullable(z13.string())),
2561
2588
  // Milliseconds between the origin click and this page load.
2562
- transit_ms: z12.optional(z12.nullable(z12.number())),
2589
+ transit_ms: z13.optional(z13.nullable(z13.number())),
2563
2590
  // True when this browser had no visitor id and took the origin's.
2564
- adopted_visitor: z12.boolean(),
2565
- page: z12.strictObject({
2566
- path: z12.string()
2591
+ adopted_visitor: z13.boolean(),
2592
+ page: z13.strictObject({
2593
+ path: z13.string()
2567
2594
  })
2568
2595
  });
2569
- var siteLinkArrivalConfigSchema = z12.strictObject({});
2596
+ var siteLinkArrivalConfigSchema = z13.strictObject({});
2570
2597
 
2571
2598
  // ../tracking-core/src/events/time-on-site.ts
2572
- import * as z13 from "zod/mini";
2573
- var timeOnSiteMetadataSchema = z13.strictObject({
2574
- duration_ms: z13.int().check(z13.nonnegative()),
2575
- page: z13.strictObject({
2576
- path: z13.string()
2599
+ import * as z14 from "zod/mini";
2600
+ var timeOnSiteMetadataSchema = z14.strictObject({
2601
+ duration_ms: z14.int().check(z14.nonnegative()),
2602
+ page: z14.strictObject({
2603
+ path: z14.string()
2577
2604
  })
2578
2605
  });
2579
- var timeOnSiteConfigSchema = z13.strictObject({
2580
- thresholdSeconds: z13.int().check(z13.positive())
2606
+ var timeOnSiteConfigSchema = z14.strictObject({
2607
+ thresholdSeconds: z14.int().check(z14.positive())
2581
2608
  });
2582
2609
 
2583
2610
  // ../tracking-core/src/events/registry.ts
@@ -2653,6 +2680,12 @@ var EVENT_REGISTRY = {
2653
2680
  metadataSchema: formSubmitMetadataSchema,
2654
2681
  configSchema: formSubmitConfigSchema
2655
2682
  },
2683
+ form_step: {
2684
+ kind: "manual",
2685
+ semantics: EVENT_SEMANTICS.form_step,
2686
+ metadataSchema: formStepMetadataSchema,
2687
+ configSchema: formStepConfigSchema
2688
+ },
2656
2689
  phone_click: {
2657
2690
  kind: "manual",
2658
2691
  semantics: EVENT_SEMANTICS.phone_click,
@@ -2679,9 +2712,14 @@ function createTypedClient(raw, registry, options = {}) {
2679
2712
  if (registry.manual?.form_submit) registerCapability("form_capture");
2680
2713
  return {
2681
2714
  trackEvent(eventType, metadata, opts) {
2715
+ const def = getEventDefinition(eventType);
2682
2716
  if (debug) {
2683
- const def = getEventDefinition(eventType);
2684
2717
  parse2(def.metadataSchema, metadata);
2718
+ } else if (!safeParse(def.metadataSchema, metadata).success) {
2719
+ console.warn(
2720
+ `[AranovaTracking] trackEvent: metadata for "${eventType}" failed schema validation; event dropped`
2721
+ );
2722
+ return;
2685
2723
  }
2686
2724
  raw.trackEvent({
2687
2725
  eventType,
@@ -3056,8 +3094,14 @@ function attachFormStart(client, config) {
3056
3094
  return `index:${forms.indexOf(form)}`;
3057
3095
  }
3058
3096
  function onFocusIn(event) {
3059
- const target = event.target;
3060
- if (!(target instanceof HTMLElement)) return;
3097
+ startFrom(event.target);
3098
+ }
3099
+ function onPointerDown(event) {
3100
+ if (event.button !== 0) return;
3101
+ startFrom(event.target);
3102
+ }
3103
+ function startFrom(target) {
3104
+ if (!(target instanceof Element)) return;
3061
3105
  const form = target.closest(selector);
3062
3106
  if (!form || form.tagName !== "FORM") return;
3063
3107
  const key = getFormKey(form);
@@ -3096,11 +3140,13 @@ function attachFormStart(client, config) {
3096
3140
  history.replaceState = patchedReplaceState;
3097
3141
  window.addEventListener("popstate", resetIfPathChanged);
3098
3142
  document.addEventListener("focusin", onFocusIn);
3143
+ document.addEventListener("pointerdown", onPointerDown, { capture: true, passive: true });
3099
3144
  return () => {
3100
3145
  history.pushState = originalPushState;
3101
3146
  history.replaceState = originalReplaceState;
3102
3147
  window.removeEventListener("popstate", resetIfPathChanged);
3103
3148
  document.removeEventListener("focusin", onFocusIn);
3149
+ document.removeEventListener("pointerdown", onPointerDown, { capture: true });
3104
3150
  };
3105
3151
  }
3106
3152
 
@@ -3687,7 +3733,7 @@ function GoogleAdsTracking(props) {
3687
3733
  import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
3688
3734
 
3689
3735
  // package.json
3690
- var version = "1.2.2";
3736
+ var version = "1.2.3";
3691
3737
 
3692
3738
  // ../tracking-core/src/phone-react.tsx
3693
3739
  import {