@aranova/tracking-react 1.8.1 → 1.9.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.
package/dist/client.mjs CHANGED
@@ -977,6 +977,7 @@ function parseBookingRules(value) {
977
977
  closed_dates: isStringList(r.closed_dates) ? r.closed_dates : [],
978
978
  special_hours: parseWindowsMap(r.special_hours),
979
979
  vehicle_required: r.vehicle_required === true,
980
+ vehicle_deferred: r.vehicle_deferred === true,
980
981
  drop_off_options: isStringList(r.drop_off_options) ? r.drop_off_options : []
981
982
  };
982
983
  }
@@ -1712,6 +1713,7 @@ function camelRules(rules) {
1712
1713
  closedDates: rules.closed_dates,
1713
1714
  specialHours: rules.special_hours,
1714
1715
  vehicleRequired: rules.vehicle_required,
1716
+ vehicleDeferred: rules.vehicle_deferred,
1715
1717
  dropOffOptions: rules.drop_off_options
1716
1718
  };
1717
1719
  }
@@ -3276,6 +3278,7 @@ function attachMultiPageSession(client, config) {
3276
3278
  }
3277
3279
 
3278
3280
  // ../tracking-core/src/triggers/form-start.ts
3281
+ var TAP_SLOP_PX = 10;
3279
3282
  function attachFormStart(client, config) {
3280
3283
  if (typeof window === "undefined" || typeof document === "undefined") {
3281
3284
  return () => {
@@ -3284,6 +3287,7 @@ function attachFormStart(client, config) {
3284
3287
  const selector = config.selector ?? "form";
3285
3288
  let firedForms = /* @__PURE__ */ new Set();
3286
3289
  let currentPath2 = window.location.pathname;
3290
+ let pendingTap = null;
3287
3291
  function getFormKey(form) {
3288
3292
  if (form.id) return `id:${form.id}`;
3289
3293
  const explicitAction = form.getAttribute("action");
@@ -3294,10 +3298,23 @@ function attachFormStart(client, config) {
3294
3298
  function onFocusIn(event) {
3295
3299
  startFrom(event.target);
3296
3300
  }
3297
- function onPointerDown(event) {
3301
+ function onClick(event) {
3298
3302
  if (event.button !== 0) return;
3299
3303
  startFrom(event.target);
3300
3304
  }
3305
+ function onPointerDown(event) {
3306
+ pendingTap = event.button === 0 ? { pointerId: event.pointerId, x: event.clientX, y: event.clientY, target: event.target } : null;
3307
+ }
3308
+ function onPointerCancel() {
3309
+ pendingTap = null;
3310
+ }
3311
+ function onPointerUp(event) {
3312
+ const tap = pendingTap;
3313
+ pendingTap = null;
3314
+ if (!tap || tap.pointerId !== event.pointerId) return;
3315
+ if (Math.hypot(event.clientX - tap.x, event.clientY - tap.y) > TAP_SLOP_PX) return;
3316
+ startFrom(tap.target);
3317
+ }
3301
3318
  function startFrom(target) {
3302
3319
  if (!(target instanceof Element)) return;
3303
3320
  const form = target.closest(selector);
@@ -3334,17 +3351,24 @@ function attachFormStart(client, config) {
3334
3351
  originalReplaceState(...args);
3335
3352
  setTimeout(resetIfPathChanged, 0);
3336
3353
  }
3354
+ const passiveCapture = { capture: true, passive: true };
3337
3355
  history.pushState = patchedPushState;
3338
3356
  history.replaceState = patchedReplaceState;
3339
3357
  window.addEventListener("popstate", resetIfPathChanged);
3340
3358
  document.addEventListener("focusin", onFocusIn);
3341
- document.addEventListener("pointerdown", onPointerDown, { capture: true, passive: true });
3359
+ document.addEventListener("click", onClick, passiveCapture);
3360
+ document.addEventListener("pointerdown", onPointerDown, passiveCapture);
3361
+ document.addEventListener("pointerup", onPointerUp, passiveCapture);
3362
+ document.addEventListener("pointercancel", onPointerCancel, passiveCapture);
3342
3363
  return () => {
3343
3364
  history.pushState = originalPushState;
3344
3365
  history.replaceState = originalReplaceState;
3345
3366
  window.removeEventListener("popstate", resetIfPathChanged);
3346
3367
  document.removeEventListener("focusin", onFocusIn);
3368
+ document.removeEventListener("click", onClick, { capture: true });
3347
3369
  document.removeEventListener("pointerdown", onPointerDown, { capture: true });
3370
+ document.removeEventListener("pointerup", onPointerUp, { capture: true });
3371
+ document.removeEventListener("pointercancel", onPointerCancel, { capture: true });
3348
3372
  };
3349
3373
  }
3350
3374
 
@@ -3934,7 +3958,7 @@ function GoogleAdsTracking(props) {
3934
3958
  import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
3935
3959
 
3936
3960
  // package.json
3937
- var version = "1.8.1";
3961
+ var version = "1.9.0";
3938
3962
 
3939
3963
  // ../tracking-core/src/phone-react.tsx
3940
3964
  import {
@@ -4257,25 +4281,31 @@ function useBookingSubmit(bookings, options = {}) {
4257
4281
  const [outcome, setOutcome] = useState4(null);
4258
4282
  const [submitting, setSubmitting] = useState4(false);
4259
4283
  const attemptKey = useRef(null);
4284
+ const [booked, setBooked] = useState4(null);
4260
4285
  const inFlight = useRef(null);
4261
4286
  const { formSubmit, simulate } = options;
4262
4287
  const submit = useCallback3(
4263
4288
  (input) => {
4264
4289
  if (inFlight.current) return inFlight.current;
4265
4290
  attemptKey.current ?? (attemptKey.current = newBookingAttemptKey());
4291
+ const key = attemptKey.current;
4266
4292
  setSubmitting(true);
4267
4293
  const run = bookings.submit(input, {
4268
- attemptKey: attemptKey.current,
4294
+ attemptKey: key,
4269
4295
  formSubmit,
4270
4296
  simulate,
4271
4297
  // The server has it: show the pending success while the final answer is polled.
4272
4298
  onPending: (pending) => {
4299
+ setBooked({ bookingId: pending.id, attemptKey: key });
4273
4300
  setOutcome(pending);
4274
4301
  setSubmitting(false);
4275
4302
  }
4276
4303
  }).then((result) => {
4277
4304
  const unrecorded = result.status === "invalid" || result.status === "stale" || result.status === "failed" && result.id === null;
4278
4305
  if (!unrecorded) attemptKey.current = null;
4306
+ if (result.status !== "invalid" && result.status !== "stale" && result.id) {
4307
+ setBooked({ bookingId: result.id, attemptKey: key });
4308
+ }
4279
4309
  setOutcome(result);
4280
4310
  return result;
4281
4311
  }).finally(() => {
@@ -4287,12 +4317,23 @@ function useBookingSubmit(bookings, options = {}) {
4287
4317
  },
4288
4318
  [bookings, formSubmit, simulate]
4289
4319
  );
4320
+ const updateBooking = useCallback3(
4321
+ async (details, target) => {
4322
+ const attempt = target ?? booked;
4323
+ if (!attempt) return { status: "not_found", id: "", message: "Nothing has been booked yet." };
4324
+ return bookings.updateBooking(attempt.bookingId, details, {
4325
+ attemptKey: attempt.attemptKey
4326
+ });
4327
+ },
4328
+ [bookings, booked]
4329
+ );
4290
4330
  const reset = useCallback3(() => {
4291
4331
  attemptKey.current = null;
4332
+ setBooked(null);
4292
4333
  setOutcome(null);
4293
4334
  }, []);
4294
4335
  const status = submitting ? "submitting" : outcome?.status ?? "idle";
4295
- return { status, outcome, submit, reset };
4336
+ return { status, outcome, booked, submit, updateBooking, reset };
4296
4337
  }
4297
4338
  export {
4298
4339
  AdPlatformTracking,