@aranova/tracking-react 1.18.0 → 1.20.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/sales.mjs CHANGED
@@ -647,8 +647,48 @@ function parseTrigger(value) {
647
647
  if (typeof t.threshold_seconds === "number") spec.threshold_seconds = t.threshold_seconds;
648
648
  if (typeof t.page_threshold === "number") spec.page_threshold = t.page_threshold;
649
649
  if (typeof t.page_name === "string") spec.page_name = t.page_name;
650
+ if (t.metric === "percent" || t.metric === "seconds") spec.metric = t.metric;
651
+ if (typeof t.threshold === "number") spec.threshold = t.threshold;
652
+ if (typeof t.video_id === "string" || t.video_id === null) spec.video_id = t.video_id;
650
653
  return spec;
651
654
  }
655
+ function parseVideoEntry(fallbackKey, entry) {
656
+ const key = typeof entry.key === "string" && entry.key ? entry.key : fallbackKey;
657
+ if (!key) return null;
658
+ const host = typeof entry.host === "string" ? entry.host : "";
659
+ const title = typeof entry.title === "string" && entry.title ? entry.title : key;
660
+ const sourcesRaw = isRecord(entry.sources) ? entry.sources : null;
661
+ const desktop = sourcesRaw && typeof sourcesRaw.desktop === "string" ? sourcesRaw.desktop : typeof entry.desktop_uid === "string" ? entry.desktop_uid : "";
662
+ if (!host || !desktop) return null;
663
+ const mobile = sourcesRaw && typeof sourcesRaw.mobile === "string" ? sourcesRaw.mobile : typeof entry.mobile_uid === "string" ? entry.mobile_uid : null;
664
+ const posterTime = typeof entry.poster_time === "number" ? entry.poster_time : typeof entry.poster_time_s === "number" ? entry.poster_time_s : 4;
665
+ return {
666
+ key,
667
+ title,
668
+ host,
669
+ sources: { desktop, mobile },
670
+ poster_time: posterTime,
671
+ duration_s: typeof entry.duration_s === "number" ? entry.duration_s : null
672
+ };
673
+ }
674
+ function parseVideos(value) {
675
+ const out = {};
676
+ if (Array.isArray(value)) {
677
+ for (const item of value) {
678
+ if (!isRecord(item)) continue;
679
+ const parsed = parseVideoEntry("", item);
680
+ if (parsed) out[parsed.key] = parsed;
681
+ }
682
+ return out;
683
+ }
684
+ if (!isRecord(value)) return out;
685
+ for (const [key, entry] of Object.entries(value)) {
686
+ if (!isRecord(entry)) continue;
687
+ const parsed = parseVideoEntry(key, entry);
688
+ if (parsed) out[parsed.key] = parsed;
689
+ }
690
+ return out;
691
+ }
652
692
  function parseConversionConfig(raw) {
653
693
  if (!raw || typeof raw !== "object") return null;
654
694
  const obj = raw;
@@ -699,7 +739,8 @@ function parseConversionConfig(raw) {
699
739
  goals,
700
740
  linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : [],
701
741
  integrations: parseIntegrations(obj.integrations),
702
- lead_forms: parseLeadForms(obj.lead_forms)
742
+ lead_forms: parseLeadForms(obj.lead_forms),
743
+ videos: parseVideos(obj.videos)
703
744
  };
704
745
  }
705
746
  function parseLeadForms(value) {
@@ -849,6 +890,21 @@ function automaticThresholdMet(goal, eventType, metadata) {
849
890
  case "form_start":
850
891
  case "phone_click":
851
892
  return true;
893
+ case "video_play":
894
+ return trigger.video_id == null || hasStringField(metadata, "video_id") && metadata.video_id === trigger.video_id;
895
+ case "video_progress": {
896
+ if (trigger.video_id != null && (!hasStringField(metadata, "video_id") || metadata.video_id !== trigger.video_id)) {
897
+ return false;
898
+ }
899
+ if (typeof trigger.threshold !== "number") return false;
900
+ if (trigger.metric === "seconds") {
901
+ return hasNumberField(metadata, "watched_s") && metadata.watched_s >= trigger.threshold;
902
+ }
903
+ if (trigger.metric === "percent") {
904
+ return hasNumberField(metadata, "max_percent") && metadata.max_percent >= trigger.threshold || hasNumberField(metadata, "watched_percent") && metadata.watched_percent >= trigger.threshold;
905
+ }
906
+ return false;
907
+ }
852
908
  default:
853
909
  return false;
854
910
  }
@@ -908,6 +964,9 @@ var RETRY_BASE_MS = 5e3;
908
964
  var RETRY_MAX_MS = 5 * 6e4;
909
965
  var runtimes = /* @__PURE__ */ new Map();
910
966
  var configuredIds = /* @__PURE__ */ new Set();
967
+ var EMPTY_GOALS = [];
968
+ var EMPTY_STRINGS = [];
969
+ var EMPTY_VIDEOS = {};
911
970
  var scriptLoad = null;
912
971
  var jsInitialized = false;
913
972
  function cacheKey(url) {
@@ -1098,11 +1157,11 @@ var TrackingConfigRuntime = class {
1098
1157
  void this.flush();
1099
1158
  }
1100
1159
  listGoals() {
1101
- return this.current?.goals ?? [];
1160
+ return this.current?.goals ?? EMPTY_GOALS;
1102
1161
  }
1103
1162
  /** Sibling hostnames for the linker — read from the cached object even while unconfirmed. */
1104
1163
  linkedHostnames() {
1105
- return this.current?.linked_hostnames ?? [];
1164
+ return this.current?.linked_hostnames ?? EMPTY_STRINGS;
1106
1165
  }
1107
1166
  /**
1108
1167
  * Integration blocks, from the cached object even while unconfirmed: the booking fallback
@@ -1115,6 +1174,14 @@ var TrackingConfigRuntime = class {
1115
1174
  leadForms() {
1116
1175
  return this.current?.lead_forms ?? null;
1117
1176
  }
1177
+ /** Configured Cloudflare Stream tracked videos for this site. */
1178
+ videos() {
1179
+ return this.current?.videos ?? EMPTY_VIDEOS;
1180
+ }
1181
+ /** Look up one configured Cloudflare Stream tracked video by key. */
1182
+ getVideo(key) {
1183
+ return this.current?.videos?.[key] ?? null;
1184
+ }
1118
1185
  async revalidateNow() {
1119
1186
  try {
1120
1187
  const headers = {};
@@ -1271,6 +1338,16 @@ var TrackingConfigRuntime = class {
1271
1338
  this.scheduleRetry();
1272
1339
  return;
1273
1340
  }
1341
+ if (outcome === "fired" && typeof window !== "undefined" && typeof window.fbq === "function") {
1342
+ try {
1343
+ window.fbq("trackCustom", item.key, {
1344
+ ...value != null ? { value } : {},
1345
+ ...currency ? { currency } : {},
1346
+ ...item.transactionId ? { transaction_id: item.transactionId } : {}
1347
+ });
1348
+ } catch {
1349
+ }
1350
+ }
1274
1351
  this.conversionQueue.shift();
1275
1352
  }
1276
1353
  }
@@ -1906,10 +1983,13 @@ var zErrorCode = z4.enum([
1906
1983
  "bad_request",
1907
1984
  "not_found",
1908
1985
  "conflict",
1986
+ "already_disposed",
1909
1987
  "gone",
1910
1988
  "incompatible_payload",
1911
1989
  "repeat_confirmation_required",
1912
1990
  "idempotency_conflict",
1991
+ "autonomy_never_auto",
1992
+ "autonomy_auto_apply_closed",
1913
1993
  "slot_unavailable",
1914
1994
  "calendar_not_connected",
1915
1995
  "calendar_disconnected",
@@ -1934,6 +2014,7 @@ var zErrorCode = z4.enum([
1934
2014
  "unknown_service",
1935
2015
  "invalid_sale_properties",
1936
2016
  "invalid_cursor",
2017
+ "site_repo_unreadable",
1937
2018
  "rate_limited",
1938
2019
  "internal_error"
1939
2020
  ]);
@@ -1942,7 +2023,7 @@ var zSaleItemEntitySchema = z4.object({
1942
2023
  external_item_id: z4.nullable(z4.string()),
1943
2024
  id: z4.uuid(),
1944
2025
  name: z4.nullable(z4.string()),
1945
- quantity: z4.string().check(z4.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
2026
+ quantity: z4.string(),
1946
2027
  unit_cost_cents: z4.nullable(z4.int()),
1947
2028
  unit_price_cents: z4.int()
1948
2029
  });
@@ -2064,6 +2145,17 @@ var zApiErrorSchema = z4.object({
2064
2145
  errors: z4._default(z4.nullish(z4.array(zValidationErrorItem)), null),
2065
2146
  request_id: z4._default(z4.nullish(z4.string()), null)
2066
2147
  });
2148
+ var zWritebackCorrectionAction = z4.enum(["retry", "restate_now"]);
2149
+ var zWritebackCorrectionState = z4.enum([
2150
+ "queued",
2151
+ "sent",
2152
+ "restated",
2153
+ "failed",
2154
+ "limit_reached",
2155
+ "voided",
2156
+ "date_changed",
2157
+ "dry_run_ok"
2158
+ ]);
2067
2159
  var zWritebackEmailSource = z4.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
2068
2160
  var zWritebackEnrichmentStatus = z4.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
2069
2161
  var zWritebackSaleUploadCounts = z4.object({
@@ -2074,9 +2166,28 @@ var zWritebackSaleUploadCounts = z4.object({
2074
2166
  total: z4._default(z4.int(), 0),
2075
2167
  uploaded: z4._default(z4.int(), 0)
2076
2168
  });
2169
+ var zWritebackValueDrift = z4.enum(["none", "open", "failed"]);
2170
+ var zWritebackCorrectionSchema = z4.object({
2171
+ action: z4.nullable(zWritebackCorrectionAction),
2172
+ can_restate: z4._default(z4.boolean(), false),
2173
+ drift: zWritebackValueDrift,
2174
+ error_message: z4.nullable(z4.string()),
2175
+ google_currency: z4.string(),
2176
+ google_value_cents: z4.int(),
2177
+ restated_at: z4.nullable(z4.iso.datetime({ offset: true })),
2178
+ restated_from_cents: z4.nullable(z4.int()),
2179
+ restatement_limit: z4.int(),
2180
+ restatements_used: z4.int(),
2181
+ sale_currency: z4.string(),
2182
+ sale_value_cents: z4.int(),
2183
+ sends_at: z4.nullable(z4.iso.datetime({ offset: true })),
2184
+ state: zWritebackCorrectionState,
2185
+ upload_id: z4.uuid()
2186
+ });
2077
2187
  var zSaleWritebackStatusSchema = z4.object({
2078
2188
  blocked_reason: z4.nullable(z4.string()),
2079
2189
  can_dispatch: z4._default(z4.boolean(), false),
2190
+ correction: z4.nullable(zWritebackCorrectionSchema),
2080
2191
  email_source: z4.nullable(zWritebackEmailSource),
2081
2192
  enrichment_status: z4.nullable(zWritebackEnrichmentStatus),
2082
2193
  gclid_attached: z4._default(z4.boolean(), false),
@@ -2094,7 +2205,6 @@ var zSaleWritebackStatusSchema = z4.object({
2094
2205
  "out_of_window",
2095
2206
  "blocked"
2096
2207
  ]),
2097
- stale: z4._default(z4.boolean(), false),
2098
2208
  uncovered_service_ids: z4.array(z4.uuid()),
2099
2209
  uploads: zWritebackSaleUploadCounts
2100
2210
  });