@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.js CHANGED
@@ -700,8 +700,48 @@ function parseTrigger(value) {
700
700
  if (typeof t.threshold_seconds === "number") spec.threshold_seconds = t.threshold_seconds;
701
701
  if (typeof t.page_threshold === "number") spec.page_threshold = t.page_threshold;
702
702
  if (typeof t.page_name === "string") spec.page_name = t.page_name;
703
+ if (t.metric === "percent" || t.metric === "seconds") spec.metric = t.metric;
704
+ if (typeof t.threshold === "number") spec.threshold = t.threshold;
705
+ if (typeof t.video_id === "string" || t.video_id === null) spec.video_id = t.video_id;
703
706
  return spec;
704
707
  }
708
+ function parseVideoEntry(fallbackKey, entry) {
709
+ const key = typeof entry.key === "string" && entry.key ? entry.key : fallbackKey;
710
+ if (!key) return null;
711
+ const host = typeof entry.host === "string" ? entry.host : "";
712
+ const title = typeof entry.title === "string" && entry.title ? entry.title : key;
713
+ const sourcesRaw = isRecord(entry.sources) ? entry.sources : null;
714
+ const desktop = sourcesRaw && typeof sourcesRaw.desktop === "string" ? sourcesRaw.desktop : typeof entry.desktop_uid === "string" ? entry.desktop_uid : "";
715
+ if (!host || !desktop) return null;
716
+ const mobile = sourcesRaw && typeof sourcesRaw.mobile === "string" ? sourcesRaw.mobile : typeof entry.mobile_uid === "string" ? entry.mobile_uid : null;
717
+ const posterTime = typeof entry.poster_time === "number" ? entry.poster_time : typeof entry.poster_time_s === "number" ? entry.poster_time_s : 4;
718
+ return {
719
+ key,
720
+ title,
721
+ host,
722
+ sources: { desktop, mobile },
723
+ poster_time: posterTime,
724
+ duration_s: typeof entry.duration_s === "number" ? entry.duration_s : null
725
+ };
726
+ }
727
+ function parseVideos(value) {
728
+ const out = {};
729
+ if (Array.isArray(value)) {
730
+ for (const item of value) {
731
+ if (!isRecord(item)) continue;
732
+ const parsed = parseVideoEntry("", item);
733
+ if (parsed) out[parsed.key] = parsed;
734
+ }
735
+ return out;
736
+ }
737
+ if (!isRecord(value)) return out;
738
+ for (const [key, entry] of Object.entries(value)) {
739
+ if (!isRecord(entry)) continue;
740
+ const parsed = parseVideoEntry(key, entry);
741
+ if (parsed) out[parsed.key] = parsed;
742
+ }
743
+ return out;
744
+ }
705
745
  function parseConversionConfig(raw) {
706
746
  if (!raw || typeof raw !== "object") return null;
707
747
  const obj = raw;
@@ -752,7 +792,8 @@ function parseConversionConfig(raw) {
752
792
  goals,
753
793
  linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : [],
754
794
  integrations: parseIntegrations(obj.integrations),
755
- lead_forms: parseLeadForms(obj.lead_forms)
795
+ lead_forms: parseLeadForms(obj.lead_forms),
796
+ videos: parseVideos(obj.videos)
756
797
  };
757
798
  }
758
799
  function parseLeadForms(value) {
@@ -902,6 +943,21 @@ function automaticThresholdMet(goal, eventType, metadata) {
902
943
  case "form_start":
903
944
  case "phone_click":
904
945
  return true;
946
+ case "video_play":
947
+ return trigger.video_id == null || hasStringField(metadata, "video_id") && metadata.video_id === trigger.video_id;
948
+ case "video_progress": {
949
+ if (trigger.video_id != null && (!hasStringField(metadata, "video_id") || metadata.video_id !== trigger.video_id)) {
950
+ return false;
951
+ }
952
+ if (typeof trigger.threshold !== "number") return false;
953
+ if (trigger.metric === "seconds") {
954
+ return hasNumberField(metadata, "watched_s") && metadata.watched_s >= trigger.threshold;
955
+ }
956
+ if (trigger.metric === "percent") {
957
+ return hasNumberField(metadata, "max_percent") && metadata.max_percent >= trigger.threshold || hasNumberField(metadata, "watched_percent") && metadata.watched_percent >= trigger.threshold;
958
+ }
959
+ return false;
960
+ }
905
961
  default:
906
962
  return false;
907
963
  }
@@ -961,6 +1017,9 @@ var RETRY_BASE_MS = 5e3;
961
1017
  var RETRY_MAX_MS = 5 * 6e4;
962
1018
  var runtimes = /* @__PURE__ */ new Map();
963
1019
  var configuredIds = /* @__PURE__ */ new Set();
1020
+ var EMPTY_GOALS = [];
1021
+ var EMPTY_STRINGS = [];
1022
+ var EMPTY_VIDEOS = {};
964
1023
  var scriptLoad = null;
965
1024
  var jsInitialized = false;
966
1025
  function cacheKey(url) {
@@ -1151,11 +1210,11 @@ var TrackingConfigRuntime = class {
1151
1210
  void this.flush();
1152
1211
  }
1153
1212
  listGoals() {
1154
- return this.current?.goals ?? [];
1213
+ return this.current?.goals ?? EMPTY_GOALS;
1155
1214
  }
1156
1215
  /** Sibling hostnames for the linker — read from the cached object even while unconfirmed. */
1157
1216
  linkedHostnames() {
1158
- return this.current?.linked_hostnames ?? [];
1217
+ return this.current?.linked_hostnames ?? EMPTY_STRINGS;
1159
1218
  }
1160
1219
  /**
1161
1220
  * Integration blocks, from the cached object even while unconfirmed: the booking fallback
@@ -1168,6 +1227,14 @@ var TrackingConfigRuntime = class {
1168
1227
  leadForms() {
1169
1228
  return this.current?.lead_forms ?? null;
1170
1229
  }
1230
+ /** Configured Cloudflare Stream tracked videos for this site. */
1231
+ videos() {
1232
+ return this.current?.videos ?? EMPTY_VIDEOS;
1233
+ }
1234
+ /** Look up one configured Cloudflare Stream tracked video by key. */
1235
+ getVideo(key) {
1236
+ return this.current?.videos?.[key] ?? null;
1237
+ }
1171
1238
  async revalidateNow() {
1172
1239
  try {
1173
1240
  const headers = {};
@@ -1324,6 +1391,16 @@ var TrackingConfigRuntime = class {
1324
1391
  this.scheduleRetry();
1325
1392
  return;
1326
1393
  }
1394
+ if (outcome === "fired" && typeof window !== "undefined" && typeof window.fbq === "function") {
1395
+ try {
1396
+ window.fbq("trackCustom", item.key, {
1397
+ ...value != null ? { value } : {},
1398
+ ...currency ? { currency } : {},
1399
+ ...item.transactionId ? { transaction_id: item.transactionId } : {}
1400
+ });
1401
+ } catch {
1402
+ }
1403
+ }
1327
1404
  this.conversionQueue.shift();
1328
1405
  }
1329
1406
  }
@@ -1995,7 +2072,7 @@ var zSaleItemEntitySchema = z4.object({
1995
2072
  external_item_id: z4.nullable(z4.string()),
1996
2073
  id: z4.uuid(),
1997
2074
  name: z4.nullable(z4.string()),
1998
- quantity: z4.string().check(z4.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
2075
+ quantity: z4.string(),
1999
2076
  unit_cost_cents: z4.nullable(z4.int()),
2000
2077
  unit_price_cents: z4.int()
2001
2078
  });
@@ -2117,6 +2194,17 @@ var zApiErrorSchema = z4.object({
2117
2194
  errors: z4._default(z4.nullish(z4.array(zValidationErrorItem)), null),
2118
2195
  request_id: z4._default(z4.nullish(z4.string()), null)
2119
2196
  });
2197
+ var zWritebackCorrectionAction = z4.enum(["retry", "restate_now"]);
2198
+ var zWritebackCorrectionState = z4.enum([
2199
+ "queued",
2200
+ "sent",
2201
+ "restated",
2202
+ "failed",
2203
+ "limit_reached",
2204
+ "voided",
2205
+ "date_changed",
2206
+ "dry_run_ok"
2207
+ ]);
2120
2208
  var zWritebackEmailSource = z4.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
2121
2209
  var zWritebackEnrichmentStatus = z4.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
2122
2210
  var zWritebackSaleUploadCounts = z4.object({
@@ -2127,9 +2215,28 @@ var zWritebackSaleUploadCounts = z4.object({
2127
2215
  total: z4._default(z4.int(), 0),
2128
2216
  uploaded: z4._default(z4.int(), 0)
2129
2217
  });
2218
+ var zWritebackValueDrift = z4.enum(["none", "open", "failed"]);
2219
+ var zWritebackCorrectionSchema = z4.object({
2220
+ action: z4.nullable(zWritebackCorrectionAction),
2221
+ can_restate: z4._default(z4.boolean(), false),
2222
+ drift: zWritebackValueDrift,
2223
+ error_message: z4.nullable(z4.string()),
2224
+ google_currency: z4.string(),
2225
+ google_value_cents: z4.int(),
2226
+ restated_at: z4.nullable(z4.iso.datetime({ offset: true })),
2227
+ restated_from_cents: z4.nullable(z4.int()),
2228
+ restatement_limit: z4.int(),
2229
+ restatements_used: z4.int(),
2230
+ sale_currency: z4.string(),
2231
+ sale_value_cents: z4.int(),
2232
+ sends_at: z4.nullable(z4.iso.datetime({ offset: true })),
2233
+ state: zWritebackCorrectionState,
2234
+ upload_id: z4.uuid()
2235
+ });
2130
2236
  var zSaleWritebackStatusSchema = z4.object({
2131
2237
  blocked_reason: z4.nullable(z4.string()),
2132
2238
  can_dispatch: z4._default(z4.boolean(), false),
2239
+ correction: z4.nullable(zWritebackCorrectionSchema),
2133
2240
  email_source: z4.nullable(zWritebackEmailSource),
2134
2241
  enrichment_status: z4.nullable(zWritebackEnrichmentStatus),
2135
2242
  gclid_attached: z4._default(z4.boolean(), false),
@@ -2147,7 +2254,6 @@ var zSaleWritebackStatusSchema = z4.object({
2147
2254
  "out_of_window",
2148
2255
  "blocked"
2149
2256
  ]),
2150
- stale: z4._default(z4.boolean(), false),
2151
2257
  uncovered_service_ids: z4.array(z4.uuid()),
2152
2258
  uploads: zWritebackSaleUploadCounts
2153
2259
  });