@aranova/tracking-react 1.18.0 → 1.19.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
  }
@@ -1942,7 +2019,7 @@ var zSaleItemEntitySchema = z4.object({
1942
2019
  external_item_id: z4.nullable(z4.string()),
1943
2020
  id: z4.uuid(),
1944
2021
  name: z4.nullable(z4.string()),
1945
- quantity: z4.string().check(z4.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
2022
+ quantity: z4.string(),
1946
2023
  unit_cost_cents: z4.nullable(z4.int()),
1947
2024
  unit_price_cents: z4.int()
1948
2025
  });
@@ -2064,6 +2141,17 @@ var zApiErrorSchema = z4.object({
2064
2141
  errors: z4._default(z4.nullish(z4.array(zValidationErrorItem)), null),
2065
2142
  request_id: z4._default(z4.nullish(z4.string()), null)
2066
2143
  });
2144
+ var zWritebackCorrectionAction = z4.enum(["retry", "restate_now"]);
2145
+ var zWritebackCorrectionState = z4.enum([
2146
+ "queued",
2147
+ "sent",
2148
+ "restated",
2149
+ "failed",
2150
+ "limit_reached",
2151
+ "voided",
2152
+ "date_changed",
2153
+ "dry_run_ok"
2154
+ ]);
2067
2155
  var zWritebackEmailSource = z4.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
2068
2156
  var zWritebackEnrichmentStatus = z4.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
2069
2157
  var zWritebackSaleUploadCounts = z4.object({
@@ -2074,9 +2162,28 @@ var zWritebackSaleUploadCounts = z4.object({
2074
2162
  total: z4._default(z4.int(), 0),
2075
2163
  uploaded: z4._default(z4.int(), 0)
2076
2164
  });
2165
+ var zWritebackValueDrift = z4.enum(["none", "open", "failed"]);
2166
+ var zWritebackCorrectionSchema = z4.object({
2167
+ action: z4.nullable(zWritebackCorrectionAction),
2168
+ can_restate: z4._default(z4.boolean(), false),
2169
+ drift: zWritebackValueDrift,
2170
+ error_message: z4.nullable(z4.string()),
2171
+ google_currency: z4.string(),
2172
+ google_value_cents: z4.int(),
2173
+ restated_at: z4.nullable(z4.iso.datetime({ offset: true })),
2174
+ restated_from_cents: z4.nullable(z4.int()),
2175
+ restatement_limit: z4.int(),
2176
+ restatements_used: z4.int(),
2177
+ sale_currency: z4.string(),
2178
+ sale_value_cents: z4.int(),
2179
+ sends_at: z4.nullable(z4.iso.datetime({ offset: true })),
2180
+ state: zWritebackCorrectionState,
2181
+ upload_id: z4.uuid()
2182
+ });
2077
2183
  var zSaleWritebackStatusSchema = z4.object({
2078
2184
  blocked_reason: z4.nullable(z4.string()),
2079
2185
  can_dispatch: z4._default(z4.boolean(), false),
2186
+ correction: z4.nullable(zWritebackCorrectionSchema),
2080
2187
  email_source: z4.nullable(zWritebackEmailSource),
2081
2188
  enrichment_status: z4.nullable(zWritebackEnrichmentStatus),
2082
2189
  gclid_attached: z4._default(z4.boolean(), false),
@@ -2094,7 +2201,6 @@ var zSaleWritebackStatusSchema = z4.object({
2094
2201
  "out_of_window",
2095
2202
  "blocked"
2096
2203
  ]),
2097
- stale: z4._default(z4.boolean(), false),
2098
2204
  uncovered_service_ids: z4.array(z4.uuid()),
2099
2205
  uploads: zWritebackSaleUploadCounts
2100
2206
  });