@aranova/tracking-react 1.5.0 → 1.7.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/README.md CHANGED
@@ -318,7 +318,14 @@ import { useBookingIntegration, useBookingSlots, useBookingSubmit } from "@arano
318
318
  const booking = useBookingIntegration(ARANOVA_TRACKING_CONFIG);
319
319
  const days = useBookingSlots(ARANOVA_TRACKING_CONFIG); // [{ date, weekday, morning, afternoon }]
320
320
  const { status, outcome, submit } = useBookingSubmit(conversions.bookings, {
321
- formSubmit: { tracking, formId: "booking-form" },
321
+ formSubmit: {
322
+ tracking,
323
+ formId: "booking-form",
324
+ // Your own questions, for our reporting only; never sent to the shop.
325
+ extraFields: [
326
+ { name: "heardVia", type: "select", label: "How did you hear about us?", value: heardVia },
327
+ ],
328
+ },
322
329
  });
323
330
 
324
331
  await submit({
@@ -339,7 +346,8 @@ await submit({
339
346
  - `conversions` is the site's one `createSalesClient({ apiKey, endpoint, firing: getTrackingConfigRuntime(...) })`;
340
347
  `.bookings` reads the rules from that runtime.
341
348
  - `outcome.status`: `created` (the shop texts and emails the customer itself; send nothing of
342
- your own), `pending` (same success; still being sent, the owner is alerted if it fails),
349
+ your own), `pending` (same success; still being sent, the owner is alerted if it fails;
350
+ `status` turns `pending` as soon as the server says so, while the final answer is polled),
343
351
  `failed` (success copy plus `outcome.fallbackUrl`, the prefilled shop page), `invalid`
344
352
  (`outcome.message`, nothing sent), `stale` (the times changed; the config is refetched).
345
353
  - `outcome.mode` (and `booking.mode` before submitting): `live` for every real customer;
@@ -354,7 +362,9 @@ await submit({
354
362
  `[{ group, options }]` in order, so render one heading per group with its choices under it.
355
363
  - `useBookingSlots` / `bookableSlots(rules, { timeZone })` offer exactly the portal's start hours,
356
364
  judged by the shop's date. `useBookingSubmit` reuses one attempt key across a double-click or
357
- a retry, and sends the visit's `form_submit` once: don't send your own for this form.
365
+ a retry, and sends the visit's `form_submit` once: don't send your own for this form. Add the
366
+ form's own questions with `formSubmit.extraFields`; a name the booking already reports
367
+ (`phone`, `email`, ...) is dropped.
358
368
  - Ask for the last name separately, and a mobile number (the shop's confirmation text goes to it).
359
369
  - Reports the `booking_integration` capability.
360
370
 
@@ -309,7 +309,15 @@ interface BookingFormSubmit {
309
309
  };
310
310
  /** The `<form id>`, so `form_start` and `form_submit` line up. */
311
311
  formId: string;
312
+ /**
313
+ * The site's own questions (e.g. "How did you hear about us?"), appended to this
314
+ * `form_submit` for our reporting; never sent to the shop. A name the booking already
315
+ * reports (`phone`, `email`, ...) is dropped, so lead matching cannot be overridden.
316
+ */
317
+ extraFields?: FormSubmitField[];
312
318
  }
319
+ /** One field of a `form_submit`. */
320
+ type FormSubmitField = NonNullable<FormSubmitMetadata["form"]["fields"]>[number];
313
321
  type BookingOutcome =
314
322
  /** The shop has the request; it texts and emails the customer itself. */
315
323
  {
@@ -353,6 +361,13 @@ interface BookingSubmitOptions {
353
361
  * fallback screens. The production API ignores it, so it can never change a real booking.
354
362
  */
355
363
  simulate?: BookingSimulation;
364
+ /**
365
+ * Called once when the server answers `pending`, before `submit` polls for the final answer
366
+ * (up to ~30 s): show the pending success right away instead of a spinner.
367
+ */
368
+ onPending?: (outcome: Extract<BookingOutcome, {
369
+ status: "pending";
370
+ }>) => void;
356
371
  }
357
372
  interface SalesBookingsClient {
358
373
  /**
@@ -367,4 +382,4 @@ interface SalesBookingsClient {
367
382
  /** A fresh per-submit key. Keep it for retries of the same submit; mint a new one after. */
368
383
  declare const newBookingAttemptKey: typeof uuidV4;
369
384
 
370
- export { type BookingDropOff as B, type ConversionConfig as C, type SalesBookingsClient as S, type TrackingConfigReference as T, type BookingFormSubmit as a, type BookingInput as b, type BookingMode as c, type BookingOutcome as d, type BookingSimulation as e, type BookingSubmitOptions as f, type ConversionConfigStore as g, getTrackingConfigRuntime as h, resolveTrackingConfigUrl as i, type BookingDayWindows as j, type ConversionIntegrations as k, TrackingConfigRuntime as l, newBookingAttemptKey as n, resolveConversionConfig as r };
385
+ export { type BookingDropOff as B, type ConversionConfig as C, type FormSubmitField as F, type SalesBookingsClient as S, type TrackingConfigReference as T, type BookingFormSubmit as a, type BookingInput as b, type BookingMode as c, type BookingOutcome as d, type BookingSimulation as e, type BookingSubmitOptions as f, type ConversionConfigStore as g, getTrackingConfigRuntime as h, resolveTrackingConfigUrl as i, type BookingDayWindows as j, type ConversionIntegrations as k, TrackingConfigRuntime as l, newBookingAttemptKey as n, resolveConversionConfig as r };
@@ -309,7 +309,15 @@ interface BookingFormSubmit {
309
309
  };
310
310
  /** The `<form id>`, so `form_start` and `form_submit` line up. */
311
311
  formId: string;
312
+ /**
313
+ * The site's own questions (e.g. "How did you hear about us?"), appended to this
314
+ * `form_submit` for our reporting; never sent to the shop. A name the booking already
315
+ * reports (`phone`, `email`, ...) is dropped, so lead matching cannot be overridden.
316
+ */
317
+ extraFields?: FormSubmitField[];
312
318
  }
319
+ /** One field of a `form_submit`. */
320
+ type FormSubmitField = NonNullable<FormSubmitMetadata["form"]["fields"]>[number];
313
321
  type BookingOutcome =
314
322
  /** The shop has the request; it texts and emails the customer itself. */
315
323
  {
@@ -353,6 +361,13 @@ interface BookingSubmitOptions {
353
361
  * fallback screens. The production API ignores it, so it can never change a real booking.
354
362
  */
355
363
  simulate?: BookingSimulation;
364
+ /**
365
+ * Called once when the server answers `pending`, before `submit` polls for the final answer
366
+ * (up to ~30 s): show the pending success right away instead of a spinner.
367
+ */
368
+ onPending?: (outcome: Extract<BookingOutcome, {
369
+ status: "pending";
370
+ }>) => void;
356
371
  }
357
372
  interface SalesBookingsClient {
358
373
  /**
@@ -367,4 +382,4 @@ interface SalesBookingsClient {
367
382
  /** A fresh per-submit key. Keep it for retries of the same submit; mint a new one after. */
368
383
  declare const newBookingAttemptKey: typeof uuidV4;
369
384
 
370
- export { type BookingDropOff as B, type ConversionConfig as C, type SalesBookingsClient as S, type TrackingConfigReference as T, type BookingFormSubmit as a, type BookingInput as b, type BookingMode as c, type BookingOutcome as d, type BookingSimulation as e, type BookingSubmitOptions as f, type ConversionConfigStore as g, getTrackingConfigRuntime as h, resolveTrackingConfigUrl as i, type BookingDayWindows as j, type ConversionIntegrations as k, TrackingConfigRuntime as l, newBookingAttemptKey as n, resolveConversionConfig as r };
385
+ export { type BookingDropOff as B, type ConversionConfig as C, type FormSubmitField as F, type SalesBookingsClient as S, type TrackingConfigReference as T, type BookingFormSubmit as a, type BookingInput as b, type BookingMode as c, type BookingOutcome as d, type BookingSimulation as e, type BookingSubmitOptions as f, type ConversionConfigStore as g, getTrackingConfigRuntime as h, resolveTrackingConfigUrl as i, type BookingDayWindows as j, type ConversionIntegrations as k, TrackingConfigRuntime as l, newBookingAttemptKey as n, resolveConversionConfig as r };
package/dist/client.d.mts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, CSSProperties, InputHTMLAttributes, ChangeEvent, FocusEvent, AnchorHTMLAttributes } from 'react';
3
3
  import { G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, h as ConsentState, f as ConsentChoiceState, g as ConsentSource, T as TrackingParams, b as TrackingEnvironment, j as PhoneConfig, P as ParsedPhone, k as PhoneDisplayFormat } from './phone-utils-CM8eUPz8.mjs';
4
- import { T as TrackingConfigReference, C as ConversionConfig, d as BookingOutcome, b as BookingInput, S as SalesBookingsClient, a as BookingFormSubmit, e as BookingSimulation } from './bookings-CGWiBxnC.mjs';
5
- import { X as TriggerRegistryConfig, Z as TypedTrackingClient, a as BookingHandoffPrefill, b as BookingIntegration, B as BookableDay } from './ingest-typed-CytXGVw4.mjs';
4
+ import { T as TrackingConfigReference, C as ConversionConfig, d as BookingOutcome, b as BookingInput, S as SalesBookingsClient, a as BookingFormSubmit, e as BookingSimulation } from './bookings-n8UUzrak.mjs';
5
+ import { X as TriggerRegistryConfig, Z as TypedTrackingClient, a as BookingHandoffPrefill, b as BookingIntegration, B as BookableDay } from './ingest-typed-ABH28Ips.mjs';
6
6
  import { CountryCode } from 'libphonenumber-js';
7
7
  import './form-submit-BLb28aCk.mjs';
8
8
  import 'zod/mini';
@@ -414,7 +414,8 @@ interface BookingSubmitState {
414
414
  /**
415
415
  * Submit state for a booking form over `salesClient.bookings`. Owns the parts that are easy to
416
416
  * get wrong: one attempt key per submit (a double-click never books twice), the visit's
417
- * `form_submit`, the stale-config refetch, and the fallback link on failure.
417
+ * `form_submit`, the stale-config refetch, and the fallback link on failure. A `pending` answer
418
+ * shows at once (`status: "pending"`) while the final one is polled; the submit stays in flight.
418
419
  */
419
420
  declare function useBookingSubmit(bookings: SalesBookingsClient, options?: {
420
421
  formSubmit?: BookingFormSubmit;
package/dist/client.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, CSSProperties, InputHTMLAttributes, ChangeEvent, FocusEvent, AnchorHTMLAttributes } from 'react';
3
3
  import { G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, h as ConsentState, f as ConsentChoiceState, g as ConsentSource, T as TrackingParams, b as TrackingEnvironment, j as PhoneConfig, P as ParsedPhone, k as PhoneDisplayFormat } from './phone-utils-l8ey3Zdm.js';
4
- import { T as TrackingConfigReference, C as ConversionConfig, d as BookingOutcome, b as BookingInput, S as SalesBookingsClient, a as BookingFormSubmit, e as BookingSimulation } from './bookings-aJuXoVwX.js';
5
- import { X as TriggerRegistryConfig, Z as TypedTrackingClient, a as BookingHandoffPrefill, b as BookingIntegration, B as BookableDay } from './ingest-typed-DpT-uFme.js';
4
+ import { T as TrackingConfigReference, C as ConversionConfig, d as BookingOutcome, b as BookingInput, S as SalesBookingsClient, a as BookingFormSubmit, e as BookingSimulation } from './bookings-B50X7GSG.js';
5
+ import { X as TriggerRegistryConfig, Z as TypedTrackingClient, a as BookingHandoffPrefill, b as BookingIntegration, B as BookableDay } from './ingest-typed-vP-DqpxO.js';
6
6
  import { CountryCode } from 'libphonenumber-js';
7
7
  import './form-submit-BLb28aCk.js';
8
8
  import 'zod/mini';
@@ -414,7 +414,8 @@ interface BookingSubmitState {
414
414
  /**
415
415
  * Submit state for a booking form over `salesClient.bookings`. Owns the parts that are easy to
416
416
  * get wrong: one attempt key per submit (a double-click never books twice), the visit's
417
- * `form_submit`, the stale-config refetch, and the fallback link on failure.
417
+ * `form_submit`, the stale-config refetch, and the fallback link on failure. A `pending` answer
418
+ * shows at once (`status: "pending"`) while the final one is polled; the submit stays in flight.
418
419
  */
419
420
  declare function useBookingSubmit(bookings: SalesBookingsClient, options?: {
420
421
  formSubmit?: BookingFormSubmit;
package/dist/client.js CHANGED
@@ -3985,7 +3985,7 @@ function GoogleAdsTracking(props) {
3985
3985
  var import_react6 = require("react");
3986
3986
 
3987
3987
  // package.json
3988
- var version = "1.5.0";
3988
+ var version = "1.7.0";
3989
3989
 
3990
3990
  // ../tracking-core/src/phone-react.tsx
3991
3991
  var import_react5 = require("react");
@@ -4308,7 +4308,16 @@ function useBookingSubmit(bookings, options = {}) {
4308
4308
  if (inFlight.current) return inFlight.current;
4309
4309
  attemptKey.current ?? (attemptKey.current = newBookingAttemptKey());
4310
4310
  setSubmitting(true);
4311
- const run = bookings.submit(input, { attemptKey: attemptKey.current, formSubmit, simulate }).then((result) => {
4311
+ const run = bookings.submit(input, {
4312
+ attemptKey: attemptKey.current,
4313
+ formSubmit,
4314
+ simulate,
4315
+ // The server has it: show the pending success while the final answer is polled.
4316
+ onPending: (pending) => {
4317
+ setOutcome(pending);
4318
+ setSubmitting(false);
4319
+ }
4320
+ }).then((result) => {
4312
4321
  const unrecorded = result.status === "invalid" || result.status === "stale" || result.status === "failed" && result.id === null;
4313
4322
  if (!unrecorded) attemptKey.current = null;
4314
4323
  setOutcome(result);