@syntrologie/runtime-sdk 2.8.0-canary.24 → 2.8.0-canary.25

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.
@@ -99,6 +99,11 @@ export interface SyntroInitResult {
99
99
  * Only non-empty values are included.
100
100
  */
101
101
  export declare function collectBrowserMetadata(): Record<string, string | string[]>;
102
+ /**
103
+ * Fetch geo data from the Cloudflare Worker, with localStorage caching.
104
+ * Returns cached data immediately on subsequent visits. Best-effort — never blocks init.
105
+ */
106
+ export declare function fetchGeo(geoHost: string): Promise<Record<string, string>>;
102
107
  /**
103
108
  * Initialize the Syntro SDK with a single token.
104
109
  *
@@ -3439,7 +3439,7 @@ function getAntiFlickerSnippet(config = {}) {
3439
3439
  }
3440
3440
 
3441
3441
  // src/version.ts
3442
- var SDK_VERSION = "2.8.0-canary.24";
3442
+ var SDK_VERSION = "2.8.0-canary.25";
3443
3443
 
3444
3444
  // src/types.ts
3445
3445
  var SDK_SCHEMA_VERSION = "2.0";
@@ -11502,13 +11502,61 @@ function collectBrowserMetadata() {
11502
11502
  }
11503
11503
  } catch {
11504
11504
  }
11505
+ try {
11506
+ const ua = navigator.userAgent;
11507
+ if (ua.includes("Edg/")) attrs.browser = "Edge";
11508
+ else if (ua.includes("OPR/") || ua.includes("Opera")) attrs.browser = "Opera";
11509
+ else if (ua.includes("Chrome/") && !ua.includes("Chromium")) attrs.browser = "Chrome";
11510
+ else if (ua.includes("Safari/") && !ua.includes("Chrome")) attrs.browser = "Safari";
11511
+ else if (ua.includes("Firefox/")) attrs.browser = "Firefox";
11512
+ if (ua.includes("Windows")) attrs.os = "Windows";
11513
+ else if (ua.includes("iPhone") || ua.includes("iPad")) attrs.os = "iOS";
11514
+ else if (ua.includes("Mac OS X") || ua.includes("Macintosh")) attrs.os = "macOS";
11515
+ else if (ua.includes("Android")) attrs.os = "Android";
11516
+ else if (ua.includes("Linux")) attrs.os = "Linux";
11517
+ } catch {
11518
+ }
11505
11519
  try {
11506
11520
  attrs.page_url = window.location.href;
11507
11521
  attrs.page_path = window.location.pathname;
11522
+ attrs.page_host = window.location.hostname;
11523
+ if (window.location.search) attrs.page_query = window.location.search;
11508
11524
  } catch {
11509
11525
  }
11510
11526
  return attrs;
11511
11527
  }
11528
+ var GEO_CACHE_KEY = "syntro_geo";
11529
+ var GEO_DEFAULT_HOST = "https://geo.syntrologie.com";
11530
+ async function fetchGeo(geoHost) {
11531
+ if (typeof window === "undefined") return {};
11532
+ try {
11533
+ const cached = localStorage.getItem(GEO_CACHE_KEY);
11534
+ if (cached) {
11535
+ const parsed = JSON.parse(cached);
11536
+ debug("Syntro Bootstrap", "Geo: using cached data:", parsed);
11537
+ return parsed;
11538
+ }
11539
+ } catch {
11540
+ }
11541
+ try {
11542
+ const res = await fetch(geoHost, { signal: AbortSignal.timeout(2e3) });
11543
+ if (res.ok) {
11544
+ const geo = await res.json();
11545
+ const cleaned = {};
11546
+ for (const [k, v] of Object.entries(geo)) {
11547
+ if (typeof v === "string" && v) cleaned[k] = v;
11548
+ }
11549
+ try {
11550
+ localStorage.setItem(GEO_CACHE_KEY, JSON.stringify(cleaned));
11551
+ } catch {
11552
+ }
11553
+ debug("Syntro Bootstrap", "Geo: fetched from worker:", cleaned);
11554
+ return cleaned;
11555
+ }
11556
+ } catch {
11557
+ }
11558
+ return {};
11559
+ }
11512
11560
  async function init(options) {
11513
11561
  var _a2;
11514
11562
  try {
@@ -11523,7 +11571,7 @@ async function init(options) {
11523
11571
  }
11524
11572
  }
11525
11573
  async function _initCore(options) {
11526
- var _a2, _b, _c, _d, _e, _f;
11574
+ var _a2, _b, _c, _d, _e, _f, _g;
11527
11575
  initLogger();
11528
11576
  debug("Syntro Bootstrap", "====== INIT ======");
11529
11577
  debug("Syntro Bootstrap", "Options:", {
@@ -11588,11 +11636,13 @@ async function _initCore(options) {
11588
11636
  const experimentHost = getEnvVar("NEXT_PUBLIC_SYNTRO_EXPERIMENT_HOST") || getEnvVar("VITE_SYNTRO_EXPERIMENT_HOST") || (payload == null ? void 0 : payload.eh);
11589
11637
  const telemetryHost = getEnvVar("NEXT_PUBLIC_SYNTRO_TELEMETRY_HOST") || getEnvVar("VITE_SYNTRO_TELEMETRY_HOST") || (payload == null ? void 0 : payload.th);
11590
11638
  const editorUrl = getEnvVar("NEXT_PUBLIC_SYNTRO_EDITOR_URL") || getEnvVar("VITE_SYNTRO_EDITOR_URL") || ((_b = options.canvas) == null ? void 0 : _b.editorUrl);
11639
+ const geoHost = (payload == null ? void 0 : payload.g) || getEnvVar("NEXT_PUBLIC_SYNTRO_GEO_HOST") || getEnvVar("VITE_SYNTRO_GEO_HOST") || GEO_DEFAULT_HOST;
11591
11640
  const cachedSegmentAttrs = loadCachedSegmentAttributes();
11592
11641
  const browserMetadata = collectBrowserMetadata();
11593
11642
  const phaseOneAttrs = { ...browserMetadata, ...cachedSegmentAttrs };
11594
11643
  debug("Syntro Bootstrap", "Phase 1: Browser metadata:", browserMetadata);
11595
11644
  debug("Syntro Bootstrap", "Phase 1: Cached segment attributes:", cachedSegmentAttrs);
11645
+ const geoPromise = fetchGeo(geoHost);
11596
11646
  let experiments;
11597
11647
  const events = createEventBus();
11598
11648
  console.log("[Syntro Bootstrap] EventBus created");
@@ -11763,11 +11813,17 @@ async function _initCore(options) {
11763
11813
  warn("Syntro Bootstrap", "Failed to load GrowthBook features:", err);
11764
11814
  }
11765
11815
  }
11816
+ const geoData = await geoPromise;
11817
+ if (experiments && Object.keys(geoData).length > 0) {
11818
+ const mergedAttrs = { ...browserMetadata, ...geoData };
11819
+ debug("Syntro Bootstrap", "Merging geo data into GrowthBook attributes:", geoData);
11820
+ (_f = experiments.setAttributes) == null ? void 0 : _f.call(experiments, mergedAttrs);
11821
+ }
11766
11822
  let baseFetcher;
11767
11823
  if (options.fetcher) {
11768
11824
  baseFetcher = options.fetcher;
11769
11825
  } else if (payload == null ? void 0 : payload.f) {
11770
- const configFetcher = createConfigFetcher(payload.f, (_f = payload.o) != null ? _f : {});
11826
+ const configFetcher = createConfigFetcher(payload.f, (_g = payload.o) != null ? _g : {});
11771
11827
  baseFetcher = async () => {
11772
11828
  var _a3;
11773
11829
  const result = await configFetcher.fetch();
@@ -11781,7 +11837,7 @@ async function _initCore(options) {
11781
11837
  }
11782
11838
  const warnedAppFailures = /* @__PURE__ */ new Set();
11783
11839
  const appLoadingFetcher = baseFetcher ? async () => {
11784
- var _a3, _b2, _c2, _d2, _e2, _f2, _g;
11840
+ var _a3, _b2, _c2, _d2, _e2, _f2, _g2;
11785
11841
  const config = await baseFetcher();
11786
11842
  console.log(
11787
11843
  "[Syntro Bootstrap] Config fetched:",
@@ -11789,7 +11845,7 @@ async function _initCore(options) {
11789
11845
  `actions=${(_d2 = (_c2 = config.actions) == null ? void 0 : _c2.length) != null ? _d2 : 0},`,
11790
11846
  `theme=${(_f2 = (_e2 = config.theme) == null ? void 0 : _e2.name) != null ? _f2 : "none"}`
11791
11847
  );
11792
- if (((_g = config.actions) == null ? void 0 : _g.length) > 0) {
11848
+ if (((_g2 = config.actions) == null ? void 0 : _g2.length) > 0) {
11793
11849
  console.log(
11794
11850
  "[Syntro Bootstrap] Actions in config:",
11795
11851
  config.actions.map(
@@ -11964,4 +12020,4 @@ export {
11964
12020
  encodeToken,
11965
12021
  Syntro
11966
12022
  };
11967
- //# sourceMappingURL=chunk-UJFBG2NR.js.map
12023
+ //# sourceMappingURL=chunk-S2VWPKFP.js.map