sitepong 0.1.13 → 0.2.1

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.
@@ -1,3 +1,3 @@
1
1
  export { addBreadcrumb, captureServerException, captureServerMessage, clearBreadcrumbs, getBreadcrumbs, getServerConfig, initServer } from '../server/index.mjs';
2
- export { C as CaptureContext, E as ErrorEvent, L as LogLevel, S as SitePongConfig } from '../types-Cms9VXx9.mjs';
3
- import '../types-BEqbz0tw.mjs';
2
+ export { C as CaptureContext, E as ErrorEvent, L as LogLevel, S as SitePongConfig } from '../types-CphqOTfm.mjs';
3
+ import '../types-DPINdOQW.mjs';
@@ -1,3 +1,3 @@
1
1
  export { addBreadcrumb, captureServerException, captureServerMessage, clearBreadcrumbs, getBreadcrumbs, getServerConfig, initServer } from '../server/index.js';
2
- export { C as CaptureContext, E as ErrorEvent, L as LogLevel, S as SitePongConfig } from '../types-DQSv7JAE.js';
3
- import '../types-BEqbz0tw.js';
2
+ export { C as CaptureContext, E as ErrorEvent, L as LogLevel, S as SitePongConfig } from '../types-BTA43eyz.js';
3
+ import '../types-DPINdOQW.js';
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var react = require('react');
4
+ require('web-vitals');
4
5
  var reactNative = require('react-native');
5
6
  var jsxRuntime = require('react/jsx-runtime');
6
7
 
@@ -609,6 +610,60 @@ function clearSession() {
609
610
  memorySessionTs = null;
610
611
  }
611
612
 
613
+ // src/analytics/utm.ts
614
+ var STORAGE_KEY2 = "sp_utm";
615
+ var UTM_KEYS = [
616
+ ["source", "utm_source"],
617
+ ["medium", "utm_medium"],
618
+ ["campaign", "utm_campaign"],
619
+ ["term", "utm_term"],
620
+ ["content", "utm_content"]
621
+ ];
622
+ function parseFromLocation() {
623
+ if (typeof window === "undefined" || !window.location || !window.location.search) return null;
624
+ let params;
625
+ try {
626
+ params = new URLSearchParams(window.location.search);
627
+ } catch {
628
+ return null;
629
+ }
630
+ const result = {};
631
+ let found = false;
632
+ for (const [key, queryKey] of UTM_KEYS) {
633
+ const value = params.get(queryKey);
634
+ if (value) {
635
+ result[key] = value;
636
+ found = true;
637
+ }
638
+ }
639
+ return found ? result : null;
640
+ }
641
+ function readStored() {
642
+ if (typeof sessionStorage === "undefined") return null;
643
+ try {
644
+ const raw = sessionStorage.getItem(STORAGE_KEY2);
645
+ if (!raw) return null;
646
+ const parsed = JSON.parse(raw);
647
+ return parsed && typeof parsed === "object" ? parsed : null;
648
+ } catch {
649
+ return null;
650
+ }
651
+ }
652
+ function writeStored(utm) {
653
+ if (typeof sessionStorage === "undefined") return;
654
+ try {
655
+ sessionStorage.setItem(STORAGE_KEY2, JSON.stringify(utm));
656
+ } catch {
657
+ }
658
+ }
659
+ function getSessionUtm() {
660
+ const stored = readStored();
661
+ if (stored) return stored;
662
+ const fresh = parseFromLocation();
663
+ if (fresh) writeStored(fresh);
664
+ return fresh;
665
+ }
666
+
612
667
  // src/analytics/autocapture.ts
613
668
  var DEFAULT_BLOCK_SELECTORS = [
614
669
  "[data-sp-no-capture]",
@@ -1015,7 +1070,9 @@ var AnalyticsManager = class {
1015
1070
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1016
1071
  url: typeof window !== "undefined" && window.location ? window.location.href : void 0,
1017
1072
  referrer: typeof document !== "undefined" && typeof document.referrer === "string" ? document.referrer : void 0,
1018
- userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0
1073
+ userAgent: typeof navigator !== "undefined" ? navigator.userAgent : void 0,
1074
+ utm: getSessionUtm() || void 0,
1075
+ appVersion: this.config.appVersion || void 0
1019
1076
  };
1020
1077
  }
1021
1078
  enqueue(event) {
@@ -1713,7 +1770,7 @@ var DEFAULT_REMOTE_CONFIG = {
1713
1770
  };
1714
1771
 
1715
1772
  // src/remote-config/manager.ts
1716
- var STORAGE_KEY2 = "sitepong_remote_config";
1773
+ var STORAGE_KEY3 = "sitepong_remote_config";
1717
1774
  var STORAGE_TS_KEY = "sitepong_remote_config_ts";
1718
1775
  var RemoteConfigManager = class {
1719
1776
  constructor(options) {
@@ -1756,7 +1813,7 @@ var RemoteConfigManager = class {
1756
1813
  const storage = this.options.storage;
1757
1814
  if (!storage) return;
1758
1815
  try {
1759
- const cached = await storage.getItem(STORAGE_KEY2);
1816
+ const cached = await storage.getItem(STORAGE_KEY3);
1760
1817
  const cachedTs = await storage.getItem(STORAGE_TS_KEY);
1761
1818
  if (cached && cachedTs) {
1762
1819
  const age = Date.now() - parseInt(cachedTs, 10);
@@ -1773,9 +1830,9 @@ var RemoteConfigManager = class {
1773
1830
  }
1774
1831
  async fetchAndApply() {
1775
1832
  try {
1776
- const platform = detectPlatform();
1833
+ const platform2 = detectPlatform();
1777
1834
  const params = new URLSearchParams({
1778
- platform,
1835
+ platform: platform2,
1779
1836
  ...this.options.sdkVersion ? { sdkVersion: this.options.sdkVersion } : {}
1780
1837
  });
1781
1838
  const response = await fetch(
@@ -1817,7 +1874,7 @@ var RemoteConfigManager = class {
1817
1874
  const storage = this.options.storage;
1818
1875
  if (!storage) return;
1819
1876
  try {
1820
- await storage.setItem(STORAGE_KEY2, JSON.stringify(this.config));
1877
+ await storage.setItem(STORAGE_KEY3, JSON.stringify(this.config));
1821
1878
  await storage.setItem(STORAGE_TS_KEY, String(Date.now()));
1822
1879
  } catch {
1823
1880
  this.log("Failed to cache remote config");
@@ -1852,18 +1909,209 @@ var RemoteConfigManager = class {
1852
1909
  }
1853
1910
  };
1854
1911
 
1912
+ // src/superlink/client.ts
1913
+ var DEFAULT_SUPERLINK_ENDPOINT = "https://pongl.ink";
1914
+ var SuperLinkClient = class {
1915
+ constructor(config = {}) {
1916
+ this.config = {
1917
+ endpoint: stripTrailingSlash(config.endpoint || DEFAULT_SUPERLINK_ENDPOINT),
1918
+ appId: config.appId,
1919
+ installId: config.installId,
1920
+ debug: config.debug ?? false
1921
+ };
1922
+ }
1923
+ /** Replace config in place (used by init() so module-level helpers see updates). */
1924
+ configure(config) {
1925
+ if (config.endpoint) this.config.endpoint = stripTrailingSlash(config.endpoint);
1926
+ if (config.appId !== void 0) this.config.appId = config.appId;
1927
+ if (config.installId !== void 0) this.config.installId = config.installId;
1928
+ if (config.debug !== void 0) this.config.debug = config.debug;
1929
+ }
1930
+ log(...args) {
1931
+ if (this.config.debug) console.warn("[SuperLink]", ...args);
1932
+ }
1933
+ /**
1934
+ * POST /match — ask the redirect engine to resolve a deferred deep link from
1935
+ * a click token (Android referrer / iOS clipboard) and/or a device
1936
+ * fingerprint. Returns `{ matched: false }` on any error.
1937
+ */
1938
+ async match(body) {
1939
+ const payload = {
1940
+ ...body,
1941
+ install_id: body.install_id ?? this.config.installId
1942
+ };
1943
+ try {
1944
+ const res = await fetch(`${this.config.endpoint}/match`, {
1945
+ method: "POST",
1946
+ headers: { "Content-Type": "application/json" },
1947
+ body: JSON.stringify(payload)
1948
+ });
1949
+ if (!res.ok) {
1950
+ this.log("match failed", res.status);
1951
+ return { matched: false };
1952
+ }
1953
+ const data = await res.json();
1954
+ return data ?? { matched: false };
1955
+ } catch (err) {
1956
+ this.log("match error", err);
1957
+ return { matched: false };
1958
+ }
1959
+ }
1960
+ /**
1961
+ * POST /events — report a lifecycle event (opened / converted) back to the
1962
+ * redirect engine, which fans out to analytics + webhooks. Best-effort.
1963
+ */
1964
+ async reportEvent(input) {
1965
+ try {
1966
+ const res = await fetch(`${this.config.endpoint}/events`, {
1967
+ method: "POST",
1968
+ headers: { "Content-Type": "application/json" },
1969
+ body: JSON.stringify({
1970
+ app_id: this.config.appId,
1971
+ install_id: this.config.installId,
1972
+ ...input
1973
+ })
1974
+ });
1975
+ if (!res.ok) this.log("event failed", input.type, res.status);
1976
+ return res.ok;
1977
+ } catch (err) {
1978
+ this.log("event error", err);
1979
+ return false;
1980
+ }
1981
+ }
1982
+ };
1983
+ function stripTrailingSlash(url) {
1984
+ return url.endsWith("/") ? url.slice(0, -1) : url;
1985
+ }
1986
+ var superlinkClient = new SuperLinkClient();
1987
+
1988
+ // src/superlink/parse.ts
1989
+ var UTM_KEYS2 = [
1990
+ ["source", "utm_source"],
1991
+ ["medium", "utm_medium"],
1992
+ ["campaign", "utm_campaign"],
1993
+ ["term", "utm_term"],
1994
+ ["content", "utm_content"]
1995
+ ];
1996
+ function parseUniversalLink(url) {
1997
+ let parsed;
1998
+ try {
1999
+ parsed = new URL(url);
2000
+ } catch {
2001
+ return null;
2002
+ }
2003
+ const params = parsed.searchParams;
2004
+ const utm = {};
2005
+ for (const [key, queryKey] of UTM_KEYS2) {
2006
+ const value = params.get(queryKey);
2007
+ if (value) utm[key] = value;
2008
+ }
2009
+ const referral = {};
2010
+ const deep_link_data = {};
2011
+ params.forEach((value, key) => {
2012
+ if (key.startsWith("r_")) {
2013
+ referral[key.slice(2)] = value;
2014
+ } else if (key.startsWith("~")) {
2015
+ deep_link_data[key.slice(1)] = value;
2016
+ }
2017
+ });
2018
+ const explicitPath = params.get("$deep_link_path") ?? params.get("dlp");
2019
+ const deep_link_path = explicitPath ?? (parsed.pathname && parsed.pathname !== "/" ? parsed.pathname : null);
2020
+ return {
2021
+ deep_link_path,
2022
+ deep_link_data,
2023
+ utm,
2024
+ referral,
2025
+ click_id: params.get("click_id"),
2026
+ match_type: "none",
2027
+ confidence: 1
2028
+ };
2029
+ }
2030
+
2031
+ // src/superlink/deferred.ts
2032
+ var handlers = /* @__PURE__ */ new Set();
2033
+ var lastMatched = null;
2034
+ function toDeepLink(res) {
2035
+ return {
2036
+ deep_link_path: res.deep_link_path ?? null,
2037
+ deep_link_data: res.deep_link_data ?? {},
2038
+ utm: res.utm ?? {},
2039
+ referral: res.referral ?? {},
2040
+ click_id: res.click_id ?? null,
2041
+ match_type: res.match_type ?? "fingerprint",
2042
+ confidence: res.confidence ?? (res.match_type && res.match_type !== "none" ? 1 : 0)
2043
+ };
2044
+ }
2045
+ function emitDeferredDeepLink(link) {
2046
+ lastMatched = link;
2047
+ for (const handler of handlers) {
2048
+ try {
2049
+ handler(link);
2050
+ } catch (err) {
2051
+ if (superlinkClient.config.debug) console.warn("[SuperLink] handler threw", err);
2052
+ }
2053
+ }
2054
+ }
2055
+ function onDeferredDeepLink(handler) {
2056
+ handlers.add(handler);
2057
+ if (lastMatched) {
2058
+ try {
2059
+ handler(lastMatched);
2060
+ } catch {
2061
+ }
2062
+ }
2063
+ return () => {
2064
+ handlers.delete(handler);
2065
+ };
2066
+ }
2067
+ function getMatchedDeepLink() {
2068
+ return lastMatched;
2069
+ }
2070
+
2071
+ // src/superlink/web.ts
2072
+ function extractIdentityMetadata(url) {
2073
+ const href = url ?? (typeof window !== "undefined" && window.location ? window.location.href : null);
2074
+ if (!href) return void 0;
2075
+ let loc;
2076
+ try {
2077
+ loc = new URL(href);
2078
+ } catch {
2079
+ return void 0;
2080
+ }
2081
+ const email = loc.searchParams.get("email");
2082
+ const phone = loc.searchParams.get("phone");
2083
+ const userId = loc.searchParams.get("user_id");
2084
+ const id = loc.searchParams.get("id");
2085
+ const customRaw = loc.searchParams.get("custom");
2086
+ const identity = {};
2087
+ if (email) identity.email = email;
2088
+ if (phone) identity.phone = phone;
2089
+ if (userId) identity.user_id = userId;
2090
+ if (id) identity.id = id;
2091
+ if (customRaw) {
2092
+ try {
2093
+ const custom = JSON.parse(decodeURIComponent(customRaw));
2094
+ if (typeof custom === "object" && custom !== null) {
2095
+ identity.custom = custom;
2096
+ }
2097
+ } catch {
2098
+ }
2099
+ }
2100
+ return Object.keys(identity).length > 0 ? identity : void 0;
2101
+ }
2102
+
1855
2103
  // src/index.ts
1856
2104
  function installFallbackEnvironment() {
1857
2105
  if (getEnvironment()) return;
1858
2106
  const g = globalThis;
1859
2107
  const hasBrowser = typeof g.window !== "undefined" && typeof g.document !== "undefined";
1860
2108
  const hasNode = !hasBrowser && !!g.process?.versions?.node;
1861
- const platform = hasBrowser ? "browser" : "node";
2109
+ const platform2 = hasBrowser ? "browser" : "node";
1862
2110
  const env2 = {
1863
- platform,
2111
+ platform: platform2,
1864
2112
  storage: null,
1865
2113
  getDeviceInfo() {
1866
- const info = { platform };
2114
+ const info = { platform: platform2 };
1867
2115
  if (g.navigator?.userAgent) info.userAgent = g.navigator.userAgent;
1868
2116
  if (hasBrowser && g.window?.screen) {
1869
2117
  info.screenWidth = g.window.screen.width;
@@ -2058,6 +2306,10 @@ var SitePongClient = class {
2058
2306
  webVitals: config.performance.webVitals,
2059
2307
  navigationTiming: config.performance.navigationTiming,
2060
2308
  resourceTiming: config.performance.resourceTiming,
2309
+ capturePageLoadTimings: config.performance.capturePageLoadTimings,
2310
+ capturePageRenderTimings: config.performance.capturePageRenderTimings,
2311
+ excludedResourceUrls: config.performance.excludedResourceUrls,
2312
+ resourceNameSanitizer: config.performance.resourceNameSanitizer,
2061
2313
  sampleRate: config.performance.sampleRate,
2062
2314
  flushInterval: config.performance.flushInterval,
2063
2315
  performanceEndpoint: config.performance.performanceEndpoint,
@@ -2766,7 +3018,7 @@ var areFlagsReady = sitepong.areFlagsReady.bind(sitepong);
2766
3018
  var refreshFlags = sitepong.refreshFlags.bind(sitepong);
2767
3019
  var track = sitepong.track.bind(sitepong);
2768
3020
  sitepong.trackPageView.bind(sitepong);
2769
- var identify = sitepong.identify.bind(sitepong);
3021
+ var identify2 = sitepong.identify.bind(sitepong);
2770
3022
  var group = sitepong.group.bind(sitepong);
2771
3023
  var resetAnalytics = sitepong.resetAnalytics.bind(sitepong);
2772
3024
  sitepong.getVisitorId.bind(sitepong);
@@ -3532,6 +3784,243 @@ function createTrackedDatabase(db, options = {}) {
3532
3784
  });
3533
3785
  }
3534
3786
 
3787
+ // src/react-native/widgets.ts
3788
+ var syncTimer = null;
3789
+ var cachedVersion = 0;
3790
+ function getNativeModule2() {
3791
+ try {
3792
+ return __require("@sitepong/expo-live-activity");
3793
+ } catch {
3794
+ return null;
3795
+ }
3796
+ }
3797
+ function getEndpoint2() {
3798
+ const cfg = sitepong.config;
3799
+ return cfg?.endpoint || "https://api.sitepong.com";
3800
+ }
3801
+ function getApiKey2() {
3802
+ const cfg = sitepong.config;
3803
+ return cfg?.apiKey || "";
3804
+ }
3805
+ async function syncWidgets(options) {
3806
+ const apiKey = getApiKey2();
3807
+ if (!apiKey) return;
3808
+ const mod = getNativeModule2();
3809
+ if (!mod) return;
3810
+ try {
3811
+ const res = await fetch(`${getEndpoint2()}/api/sdk/widgets/config`, {
3812
+ headers: { "X-API-Key": apiKey }
3813
+ });
3814
+ if (!res.ok) return;
3815
+ const data = await res.json();
3816
+ const widgets = data.widgets || [];
3817
+ const maxVersion = widgets.reduce((max, w) => Math.max(max, w.version), 0);
3818
+ if (maxVersion <= cachedVersion && cachedVersion > 0) return;
3819
+ cachedVersion = maxVersion;
3820
+ await mod.syncWidgetConfigs(JSON.stringify(widgets));
3821
+ } catch (err) {
3822
+ console.warn("[SitePong] Widget sync failed:", err);
3823
+ }
3824
+ if (syncTimer) clearInterval(syncTimer);
3825
+ const interval = options?.refreshInterval ?? 9e5;
3826
+ syncTimer = setInterval(() => syncWidgets(options), interval);
3827
+ }
3828
+ async function updateWidgetData(data) {
3829
+ const mod = getNativeModule2();
3830
+ if (!mod) return;
3831
+ try {
3832
+ await mod.updateWidgetData(JSON.stringify(data));
3833
+ } catch (err) {
3834
+ console.warn("[SitePong] Widget data update failed:", err);
3835
+ }
3836
+ }
3837
+ function triggerWidgetRefresh() {
3838
+ const mod = getNativeModule2();
3839
+ if (!mod) return;
3840
+ mod.updateWidgetData("{}").catch(() => {
3841
+ });
3842
+ }
3843
+ function stopWidgetSync() {
3844
+ if (syncTimer) {
3845
+ clearInterval(syncTimer);
3846
+ syncTimer = null;
3847
+ }
3848
+ }
3849
+ var started = false;
3850
+ function platform() {
3851
+ if (reactNative.Platform.OS === "ios") return "ios";
3852
+ if (reactNative.Platform.OS === "android") return "android";
3853
+ return "other";
3854
+ }
3855
+ function locale() {
3856
+ try {
3857
+ const tag = typeof Intl !== "undefined" && typeof Intl.DateTimeFormat === "function" ? Intl.DateTimeFormat().resolvedOptions().locale : void 0;
3858
+ return tag || void 0;
3859
+ } catch {
3860
+ return void 0;
3861
+ }
3862
+ }
3863
+ function collectFingerprint() {
3864
+ const fp = { platform: platform() };
3865
+ const osVersion = reactNative.Platform.Version;
3866
+ if (osVersion !== void 0 && osVersion !== null) fp.os_version = String(osVersion);
3867
+ fp.os = reactNative.Platform.OS;
3868
+ const lang = locale();
3869
+ if (lang) fp.language = lang;
3870
+ try {
3871
+ const device = __require("expo-device");
3872
+ if (device?.modelName) fp.device_model = device.modelName;
3873
+ } catch {
3874
+ }
3875
+ return fp;
3876
+ }
3877
+ async function readPlayInstallReferrer() {
3878
+ if (reactNative.Platform.OS !== "android") return void 0;
3879
+ let mod = null;
3880
+ try {
3881
+ mod = __require("react-native-play-install-referrer");
3882
+ } catch {
3883
+ return void 0;
3884
+ }
3885
+ const PlayInstallReferrer = mod?.PlayInstallReferrer;
3886
+ if (!PlayInstallReferrer) return void 0;
3887
+ const referrer = await new Promise((resolve) => {
3888
+ try {
3889
+ PlayInstallReferrer.getInstallReferrerInfo((info, error) => {
3890
+ if (error || !info?.installReferrer) return resolve(void 0);
3891
+ resolve(info.installReferrer);
3892
+ });
3893
+ } catch {
3894
+ resolve(void 0);
3895
+ }
3896
+ });
3897
+ if (!referrer) return void 0;
3898
+ try {
3899
+ const params = new URLSearchParams(referrer);
3900
+ return params.get("click_id") ?? params.get("referrer") ?? void 0;
3901
+ } catch {
3902
+ return void 0;
3903
+ }
3904
+ }
3905
+ async function readClipboardToken() {
3906
+ if (reactNative.Platform.OS !== "ios") return void 0;
3907
+ let value;
3908
+ try {
3909
+ const clip = __require("@react-native-clipboard/clipboard");
3910
+ const Clipboard = clip?.default ?? clip;
3911
+ if (Clipboard?.getString) {
3912
+ value = await Clipboard.getString();
3913
+ }
3914
+ } catch {
3915
+ }
3916
+ if (value == null) {
3917
+ try {
3918
+ const expoClip = __require("expo-clipboard");
3919
+ if (expoClip?.getStringAsync) {
3920
+ value = await expoClip.getStringAsync();
3921
+ }
3922
+ } catch {
3923
+ }
3924
+ }
3925
+ return hasSuperLinkToken(value) ? value.trim() : void 0;
3926
+ }
3927
+ function hasSuperLinkToken(value) {
3928
+ if (!value) return false;
3929
+ const trimmed = value.trim();
3930
+ if (/^splk:[\w-]+$/i.test(trimmed)) return true;
3931
+ if (/\/c\/[\w-]+/i.test(trimmed)) return true;
3932
+ if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmed)) return true;
3933
+ return false;
3934
+ }
3935
+ async function initSuperLinkRN(config = {}, identityOverride) {
3936
+ superlinkClient.configure(config);
3937
+ if (started) return getMatchedDeepLink();
3938
+ started = true;
3939
+ const fingerprint = collectFingerprint();
3940
+ const [referrer, clipboardToken] = await Promise.all([
3941
+ readPlayInstallReferrer(),
3942
+ readClipboardToken()
3943
+ ]);
3944
+ let identity = identityOverride;
3945
+ if (!identity && clipboardToken) {
3946
+ try {
3947
+ identity = extractIdentityMetadata(clipboardToken);
3948
+ } catch {
3949
+ }
3950
+ }
3951
+ const res = await superlinkClient.match({
3952
+ fingerprint,
3953
+ ...referrer ? { referrer } : {},
3954
+ ...clipboardToken ? { clipboard_token: clipboardToken } : {},
3955
+ ...identity ? { identity } : {}
3956
+ });
3957
+ if (!res.matched) return null;
3958
+ const link = toDeepLink(res);
3959
+ emitDeferredDeepLink(link);
3960
+ return link;
3961
+ }
3962
+ async function identify3(identity) {
3963
+ if (!identity || Object.keys(identity).length === 0) return null;
3964
+ const res = await superlinkClient.match({
3965
+ identity,
3966
+ fingerprint: collectFingerprint()
3967
+ });
3968
+ if (!res.matched) return null;
3969
+ const link = toDeepLink(res);
3970
+ emitDeferredDeepLink(link);
3971
+ return link;
3972
+ }
3973
+ async function completeFromScan2(scanned) {
3974
+ if (!scanned) return null;
3975
+ const res = await superlinkClient.match({
3976
+ qr_token: scanned,
3977
+ fingerprint: collectFingerprint()
3978
+ });
3979
+ if (!res.matched) return null;
3980
+ const link = toDeepLink(res);
3981
+ emitDeferredDeepLink(link);
3982
+ return link;
3983
+ }
3984
+ function handleUniversalLink(url) {
3985
+ const link = parseUniversalLink(url);
3986
+ if (!link) return null;
3987
+ void superlinkClient.reportEvent({
3988
+ type: "opened",
3989
+ click_id: link.click_id,
3990
+ platform: platform(),
3991
+ properties: { surface: "native", url }
3992
+ });
3993
+ return link;
3994
+ }
3995
+ function createSuperLinkListener(Linking, onLink) {
3996
+ const onUrl = (event) => {
3997
+ const link = handleUniversalLink(event.url);
3998
+ if (link) onLink(link);
3999
+ };
4000
+ Linking.getInitialURL().then((url) => {
4001
+ if (url) onUrl({ url });
4002
+ }).catch(() => {
4003
+ });
4004
+ const subscription = Linking.addEventListener("url", onUrl);
4005
+ return () => {
4006
+ if (subscription && typeof subscription.remove === "function") {
4007
+ subscription.remove();
4008
+ } else if (Linking.removeEventListener) {
4009
+ Linking.removeEventListener("url", onUrl);
4010
+ }
4011
+ };
4012
+ }
4013
+ async function reportConversion(props = {}) {
4014
+ const matched = getMatchedDeepLink();
4015
+ return superlinkClient.reportEvent({
4016
+ type: "converted",
4017
+ click_id: matched?.click_id ?? null,
4018
+ platform: platform(),
4019
+ match_type: matched?.match_type,
4020
+ properties: props
4021
+ });
4022
+ }
4023
+
3535
4024
  // src/entries/rn.ts
3536
4025
  var env = createRNEnvironment();
3537
4026
  setEnvironment(env);
@@ -3549,8 +4038,10 @@ exports.captureMessage = captureMessage;
3549
4038
  exports.clearAnonymousId = clearAnonymousId;
3550
4039
  exports.clearUser = clearUser;
3551
4040
  exports.collectDeviceInfo = collectDeviceInfo;
4041
+ exports.completeFromScan = completeFromScan2;
3552
4042
  exports.createAsyncStorageAdapter = createAsyncStorageAdapter;
3553
4043
  exports.createNavigationTracker = createNavigationTracker;
4044
+ exports.createSuperLinkListener = createSuperLinkListener;
3554
4045
  exports.createTrackedDatabase = createTrackedDatabase;
3555
4046
  exports.endLiveActivity = endLiveActivity;
3556
4047
  exports.fetchNativeDeviceSignals = fetchNativeDeviceSignals;
@@ -3561,22 +4052,28 @@ exports.flushScreenRecordingOnError = flushScreenRecordingOnError;
3561
4052
  exports.getAllFlags = getAllFlags;
3562
4053
  exports.getAnonymousId = getAnonymousId;
3563
4054
  exports.getFlag = getFlag;
4055
+ exports.getMatchedDeepLink = getMatchedDeepLink;
3564
4056
  exports.getRemoteConfig = getRemoteConfig;
3565
4057
  exports.getVariant = getVariant;
3566
4058
  exports.getVariantPayload = getVariantPayload2;
3567
4059
  exports.group = group;
3568
- exports.identify = identify;
4060
+ exports.handleUniversalLink = handleUniversalLink;
4061
+ exports.identify = identify2;
3569
4062
  exports.initRN = initRN;
4063
+ exports.initSuperLinkRN = initSuperLinkRN;
3570
4064
  exports.isInitialized = isInitialized;
3571
4065
  exports.isRemoteConfigFeatureEnabled = isRemoteConfigFeatureEnabled;
3572
4066
  exports.isScreenRecording = isScreenRecording;
3573
4067
  exports.markColdStart = markColdStart;
4068
+ exports.onDeferredDeepLink = onDeferredDeepLink;
3574
4069
  exports.onRemoteConfigChange = onRemoteConfigChange;
4070
+ exports.parseUniversalLink = parseUniversalLink;
3575
4071
  exports.refreshFlags = refreshFlags;
3576
4072
  exports.registerDeviceToken = registerDeviceToken;
3577
4073
  exports.registerLiveActivityToken = registerLiveActivityToken;
3578
4074
  exports.registerPushToStartToken = registerPushToStartToken;
3579
4075
  exports.registerPushToken = registerPushToken;
4076
+ exports.reportConversion = reportConversion;
3580
4077
  exports.resetAnalytics = resetAnalytics;
3581
4078
  exports.setAnonymousId = setAnonymousId;
3582
4079
  exports.setContext = setContext;
@@ -3588,7 +4085,12 @@ exports.setupNetworkInterception = setupNetworkInterception;
3588
4085
  exports.setupRNErrorHandler = setupRNErrorHandler;
3589
4086
  exports.startScreenRecording = startScreenRecording;
3590
4087
  exports.stopScreenRecording = stopScreenRecording;
4088
+ exports.stopWidgetSync = stopWidgetSync;
4089
+ exports.superlinkIdentify = identify3;
4090
+ exports.syncWidgets = syncWidgets;
3591
4091
  exports.track = track;
4092
+ exports.triggerWidgetRefresh = triggerWidgetRefresh;
4093
+ exports.updateWidgetData = updateWidgetData;
3592
4094
  exports.useAppState = useAppState;
3593
4095
  exports.useRNPerformance = useRNPerformance;
3594
4096
  exports.useRemoteConfig = useRemoteConfig;