@nexushub/client 1.1.8 → 1.1.11

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/index.cjs CHANGED
@@ -939,7 +939,7 @@ var ContentEngine = class {
939
939
  );
940
940
  if (this.config.debug && duration > 100) {
941
941
  console.warn(
942
- `[NexusHub] \u26A0\uFE0F getPage("${slug}") took ${duration.toFixed(2)}ms`
942
+ `[GN-Apex] \u26A0\uFE0F getPage("${slug}") took ${duration.toFixed(2)}ms`
943
943
  );
944
944
  }
945
945
  return result;
@@ -976,7 +976,7 @@ var ContentEngine = class {
976
976
  }
977
977
  }
978
978
  if (this.circuitBreaker.isOpen()) {
979
- throw new Error("[NexusHub] Circuit open. API is unavailable.");
979
+ throw new Error("[GN-Apex] Circuit open. API is unavailable.");
980
980
  }
981
981
  try {
982
982
  await this.rateLimiter.checkLimit();
@@ -993,21 +993,22 @@ var ContentEngine = class {
993
993
  return includeMetadata ? data : data.data;
994
994
  } catch (error) {
995
995
  this.circuitBreaker.recordFailure();
996
- if (process.env.NODE_ENV === "development") {
997
- try {
998
- const local = await this.localCache.getPage(slug);
999
- if (local) {
1000
- return includeMetadata ? {
1001
- data: local,
1002
- metadata: {
1003
- timestamp: Date.now(),
1004
- expiresAt: Infinity,
1005
- tags: []
1006
- }
1007
- } : local;
1008
- }
1009
- } catch {
996
+ try {
997
+ const local = await this.localCache.getPage(slug);
998
+ if (local) {
999
+ console.warn(
1000
+ `[GN-Apex] \u26A0\uFE0F Network timeout on '${slug}', successfully recovered from local cache.`
1001
+ );
1002
+ return includeMetadata ? {
1003
+ data: local,
1004
+ metadata: {
1005
+ timestamp: Date.now(),
1006
+ expiresAt: Infinity,
1007
+ tags: []
1008
+ }
1009
+ } : local;
1010
1010
  }
1011
+ } catch {
1011
1012
  }
1012
1013
  throw this.normalizeError(error, `Failed to fetch page '${slug}'`);
1013
1014
  }
@@ -1036,17 +1037,17 @@ var ContentEngine = class {
1036
1037
  localCollection,
1037
1038
  normalizedQuery
1038
1039
  );
1039
- return result;
1040
+ return includeMetadata ? result : result;
1040
1041
  }
1041
1042
  } catch {
1042
1043
  }
1043
1044
  }
1044
1045
  if (this.circuitBreaker.isOpen()) {
1045
- throw new Error("[NexusHub] Circuit open. API is unavailable.");
1046
+ throw new Error("[GN-Apex] Circuit open. API is unavailable.");
1046
1047
  }
1047
1048
  try {
1048
1049
  await this.rateLimiter.checkLimit();
1049
- const result = await this.backoff.execute(async () => {
1050
+ const entry = await this.backoff.execute(async () => {
1050
1051
  return this.fetchCollection(
1051
1052
  collectionId,
1052
1053
  normalizedQuery,
@@ -1057,20 +1058,22 @@ var ContentEngine = class {
1057
1058
  );
1058
1059
  });
1059
1060
  this.circuitBreaker.recordSuccess();
1060
- return includeMetadata ? result : result.data;
1061
+ return includeMetadata ? entry : entry.data;
1061
1062
  } catch (error) {
1062
1063
  this.circuitBreaker.recordFailure();
1063
- if (process.env.NODE_ENV === "development") {
1064
- try {
1065
- const localCollection = await this.localCache.getCollection(collectionId);
1066
- if (localCollection) {
1067
- return this.applyLocalQuery(
1068
- localCollection,
1069
- normalizedQuery
1070
- );
1071
- }
1072
- } catch {
1064
+ try {
1065
+ const localCollection = await this.localCache.getCollection(collectionId);
1066
+ if (localCollection) {
1067
+ console.warn(
1068
+ `[GN-Apex] \u26A0\uFE0F Network timeout on '${collectionId}', successfully recovered from local cache.`
1069
+ );
1070
+ const result = this.applyLocalQuery(
1071
+ localCollection,
1072
+ normalizedQuery
1073
+ );
1074
+ return includeMetadata ? result : result;
1073
1075
  }
1076
+ } catch {
1074
1077
  }
1075
1078
  throw this.normalizeError(
1076
1079
  error,
@@ -1129,14 +1132,15 @@ var ContentEngine = class {
1129
1132
  }
1130
1133
  return data;
1131
1134
  } catch (error) {
1132
- if (process.env.NODE_ENV === "development") {
1133
- try {
1134
- const localGlobals = await this.localCache.getGlobals();
1135
- if (localGlobals) {
1136
- return localGlobals;
1137
- }
1138
- } catch {
1135
+ try {
1136
+ const localGlobals = await this.localCache.getGlobals();
1137
+ if (localGlobals) {
1138
+ console.warn(
1139
+ `[GN-Apex] \u26A0\uFE0F Network timeout on globals, successfully recovered from local cache.`
1140
+ );
1141
+ return localGlobals;
1139
1142
  }
1143
+ } catch {
1140
1144
  }
1141
1145
  throw this.normalizeError(error, "Failed to fetch globals");
1142
1146
  }
@@ -1287,7 +1291,7 @@ var ContentEngine = class {
1287
1291
  };
1288
1292
  }
1289
1293
  writeCache(key, data, options) {
1290
- const ttlSeconds = options.revalidate === false ? 60 : Math.max(1, options.revalidate);
1294
+ const ttlSeconds = options.revalidate === false ? 5 : Math.max(1, options.revalidate);
1291
1295
  if (this.cacheStrategy === "memory") {
1292
1296
  this.memoryCache.set(key, data, {
1293
1297
  tags: options.tags,
@@ -1450,7 +1454,7 @@ var ContentEngine = class {
1450
1454
  }
1451
1455
  async fetchWithTimeout(url, options = {}) {
1452
1456
  const {
1453
- timeout = this.config.timeout || 1e4,
1457
+ timeout = this.config.timeout || 25e3,
1454
1458
  tags = [],
1455
1459
  revalidate,
1456
1460
  forceRefresh = false,
@@ -1628,7 +1632,6 @@ var VitalsCollector = class {
1628
1632
  tcp_connect: navEntry.connectEnd - navEntry.connectStart,
1629
1633
  request_time: navEntry.responseEnd - navEntry.requestStart,
1630
1634
  dom_load: navEntry.domComplete - navEntry.domInteractive,
1631
- // NEW: raw fields matching Rust NavigationTiming struct
1632
1635
  domain_lookup_start: navEntry.domainLookupStart,
1633
1636
  domain_lookup_end: navEntry.domainLookupEnd,
1634
1637
  connect_start: navEntry.connectStart,
@@ -1641,8 +1644,10 @@ var VitalsCollector = class {
1641
1644
  "resource"
1642
1645
  );
1643
1646
  if (resourceEntries.length > 0) {
1644
- this.metrics.resources = resourceEntries.filter((r) => !r.name.includes("/api/collect")).sort((a, b) => b.duration - a.duration).slice(0, 20).map((r) => ({
1645
- name: r.name,
1647
+ this.metrics.resources = resourceEntries.filter(
1648
+ (r) => !r.name.includes("/api/collect") && !r.name.includes("/analytics") && !r.name.includes("sentry.gnapex.com")
1649
+ ).sort((a, b) => b.duration - a.duration).slice(0, 5).map((r) => ({
1650
+ name: r.name.length > 120 ? r.name.substring(0, 120) + "..." : r.name,
1646
1651
  initiatorType: r.initiatorType,
1647
1652
  duration: Math.round(r.duration),
1648
1653
  transferSize: r.transferSize > 0 ? r.transferSize : void 0,
@@ -1674,7 +1679,7 @@ var VitalsCollector = class {
1674
1679
  var vitalsCollector = new VitalsCollector();
1675
1680
  var initVitals = (_tracker) => {
1676
1681
  if (process.env.NODE_ENV === "development") {
1677
- console.log("[NexusHub] Web Vitals monitoring active");
1682
+ console.log("[GN-Apex] Web Vitals monitoring active");
1678
1683
  }
1679
1684
  };
1680
1685
 
@@ -1827,7 +1832,8 @@ var Tracker = class {
1827
1832
  this.anonymousId = "";
1828
1833
  this.isFlushing = false;
1829
1834
  this.flushPromise = null;
1830
- this.batchSize = 25;
1835
+ // 🛡️ Batch size set to 10 to keep payloads strictly under Actix 32KB limit
1836
+ this.batchSize = 10;
1831
1837
  this.config = config;
1832
1838
  this.endpoint = `${this.config.analyticsUrl}/api/collect`;
1833
1839
  this.circuitBreaker = new CircuitBreaker();
@@ -1839,7 +1845,7 @@ var Tracker = class {
1839
1845
  }
1840
1846
  async initSession() {
1841
1847
  this.visitorId = await getVisitorId(
1842
- this.config.privacy?.fingerprinting ?? false
1848
+ this.config.privacy?.fingerprinting ?? true
1843
1849
  );
1844
1850
  let anonId = safeGetItem("nexus_anon_id");
1845
1851
  if (!anonId) {
@@ -1865,10 +1871,11 @@ var Tracker = class {
1865
1871
  if (typeof window === "undefined") return;
1866
1872
  safeSetItem("nexus_last_active", Date.now().toString());
1867
1873
  const entropy = await getDeviceEntropy(
1868
- this.config.privacy?.fingerprinting ?? false
1874
+ this.config.privacy?.fingerprinting ?? true
1869
1875
  );
1870
- const perfMetrics = vitalsCollector.getMetricsSnapshot();
1871
- const utmParams = extractUtmParams(window.location.href);
1876
+ const isPageView = eventType === "page_view" || eventType === "performance";
1877
+ const perfMetrics = isPageView ? vitalsCollector.getMetricsSnapshot() : void 0;
1878
+ const utmParams = isPageView ? extractUtmParams(window.location.href) : void 0;
1872
1879
  const payload = {
1873
1880
  projectId: this.config.projectId,
1874
1881
  sessionId: this.sessionId,
@@ -1877,10 +1884,9 @@ var Tracker = class {
1877
1884
  messageId: generateUUID(),
1878
1885
  sentAt: (/* @__PURE__ */ new Date()).toISOString(),
1879
1886
  version: SDK_VERSION,
1880
- // Dynamically synced to SDK 1.1.0
1881
1887
  url: window.location.href,
1882
- referrer: document.referrer,
1883
- userAgent: window.navigator.userAgent,
1888
+ referrer: isPageView ? document.referrer : void 0,
1889
+ userAgent: isPageView ? window.navigator.userAgent : void 0,
1884
1890
  screenWidth: window.screen.width,
1885
1891
  screenHeight: window.screen.height,
1886
1892
  language: window.navigator.language,
@@ -1943,6 +1949,10 @@ var Tracker = class {
1943
1949
  } catch {
1944
1950
  response = void 0;
1945
1951
  }
1952
+ if (response && response.status === 413) {
1953
+ await eventStorage.remove(storedEvents.map((e) => e.id));
1954
+ return;
1955
+ }
1946
1956
  if (!response || response.status === 404 || response.status === 405) {
1947
1957
  const results = await Promise.allSettled(
1948
1958
  payloads.map(
@@ -1955,7 +1965,7 @@ var Tracker = class {
1955
1965
  )
1956
1966
  );
1957
1967
  const successIds = results.flatMap(
1958
- (r, i) => r.status === "fulfilled" && r.value.ok ? [storedEvents[i].id] : []
1968
+ (r, i) => r.status === "fulfilled" && (r.value.ok || r.value.status === 413) ? [storedEvents[i].id] : []
1959
1969
  );
1960
1970
  if (successIds.length) await eventStorage.remove(successIds);
1961
1971
  if (successIds.length === storedEvents.length) {
package/dist/index.js CHANGED
@@ -883,7 +883,7 @@ var ContentEngine = class {
883
883
  );
884
884
  if (this.config.debug && duration > 100) {
885
885
  console.warn(
886
- `[NexusHub] \u26A0\uFE0F getPage("${slug}") took ${duration.toFixed(2)}ms`
886
+ `[GN-Apex] \u26A0\uFE0F getPage("${slug}") took ${duration.toFixed(2)}ms`
887
887
  );
888
888
  }
889
889
  return result;
@@ -920,7 +920,7 @@ var ContentEngine = class {
920
920
  }
921
921
  }
922
922
  if (this.circuitBreaker.isOpen()) {
923
- throw new Error("[NexusHub] Circuit open. API is unavailable.");
923
+ throw new Error("[GN-Apex] Circuit open. API is unavailable.");
924
924
  }
925
925
  try {
926
926
  await this.rateLimiter.checkLimit();
@@ -937,21 +937,22 @@ var ContentEngine = class {
937
937
  return includeMetadata ? data : data.data;
938
938
  } catch (error) {
939
939
  this.circuitBreaker.recordFailure();
940
- if (process.env.NODE_ENV === "development") {
941
- try {
942
- const local = await this.localCache.getPage(slug);
943
- if (local) {
944
- return includeMetadata ? {
945
- data: local,
946
- metadata: {
947
- timestamp: Date.now(),
948
- expiresAt: Infinity,
949
- tags: []
950
- }
951
- } : local;
952
- }
953
- } catch {
940
+ try {
941
+ const local = await this.localCache.getPage(slug);
942
+ if (local) {
943
+ console.warn(
944
+ `[GN-Apex] \u26A0\uFE0F Network timeout on '${slug}', successfully recovered from local cache.`
945
+ );
946
+ return includeMetadata ? {
947
+ data: local,
948
+ metadata: {
949
+ timestamp: Date.now(),
950
+ expiresAt: Infinity,
951
+ tags: []
952
+ }
953
+ } : local;
954
954
  }
955
+ } catch {
955
956
  }
956
957
  throw this.normalizeError(error, `Failed to fetch page '${slug}'`);
957
958
  }
@@ -980,17 +981,17 @@ var ContentEngine = class {
980
981
  localCollection,
981
982
  normalizedQuery
982
983
  );
983
- return result;
984
+ return includeMetadata ? result : result;
984
985
  }
985
986
  } catch {
986
987
  }
987
988
  }
988
989
  if (this.circuitBreaker.isOpen()) {
989
- throw new Error("[NexusHub] Circuit open. API is unavailable.");
990
+ throw new Error("[GN-Apex] Circuit open. API is unavailable.");
990
991
  }
991
992
  try {
992
993
  await this.rateLimiter.checkLimit();
993
- const result = await this.backoff.execute(async () => {
994
+ const entry = await this.backoff.execute(async () => {
994
995
  return this.fetchCollection(
995
996
  collectionId,
996
997
  normalizedQuery,
@@ -1001,20 +1002,22 @@ var ContentEngine = class {
1001
1002
  );
1002
1003
  });
1003
1004
  this.circuitBreaker.recordSuccess();
1004
- return includeMetadata ? result : result.data;
1005
+ return includeMetadata ? entry : entry.data;
1005
1006
  } catch (error) {
1006
1007
  this.circuitBreaker.recordFailure();
1007
- if (process.env.NODE_ENV === "development") {
1008
- try {
1009
- const localCollection = await this.localCache.getCollection(collectionId);
1010
- if (localCollection) {
1011
- return this.applyLocalQuery(
1012
- localCollection,
1013
- normalizedQuery
1014
- );
1015
- }
1016
- } catch {
1008
+ try {
1009
+ const localCollection = await this.localCache.getCollection(collectionId);
1010
+ if (localCollection) {
1011
+ console.warn(
1012
+ `[GN-Apex] \u26A0\uFE0F Network timeout on '${collectionId}', successfully recovered from local cache.`
1013
+ );
1014
+ const result = this.applyLocalQuery(
1015
+ localCollection,
1016
+ normalizedQuery
1017
+ );
1018
+ return includeMetadata ? result : result;
1017
1019
  }
1020
+ } catch {
1018
1021
  }
1019
1022
  throw this.normalizeError(
1020
1023
  error,
@@ -1073,14 +1076,15 @@ var ContentEngine = class {
1073
1076
  }
1074
1077
  return data;
1075
1078
  } catch (error) {
1076
- if (process.env.NODE_ENV === "development") {
1077
- try {
1078
- const localGlobals = await this.localCache.getGlobals();
1079
- if (localGlobals) {
1080
- return localGlobals;
1081
- }
1082
- } catch {
1079
+ try {
1080
+ const localGlobals = await this.localCache.getGlobals();
1081
+ if (localGlobals) {
1082
+ console.warn(
1083
+ `[GN-Apex] \u26A0\uFE0F Network timeout on globals, successfully recovered from local cache.`
1084
+ );
1085
+ return localGlobals;
1083
1086
  }
1087
+ } catch {
1084
1088
  }
1085
1089
  throw this.normalizeError(error, "Failed to fetch globals");
1086
1090
  }
@@ -1231,7 +1235,7 @@ var ContentEngine = class {
1231
1235
  };
1232
1236
  }
1233
1237
  writeCache(key, data, options) {
1234
- const ttlSeconds = options.revalidate === false ? 60 : Math.max(1, options.revalidate);
1238
+ const ttlSeconds = options.revalidate === false ? 5 : Math.max(1, options.revalidate);
1235
1239
  if (this.cacheStrategy === "memory") {
1236
1240
  this.memoryCache.set(key, data, {
1237
1241
  tags: options.tags,
@@ -1394,7 +1398,7 @@ var ContentEngine = class {
1394
1398
  }
1395
1399
  async fetchWithTimeout(url, options = {}) {
1396
1400
  const {
1397
- timeout = this.config.timeout || 1e4,
1401
+ timeout = this.config.timeout || 25e3,
1398
1402
  tags = [],
1399
1403
  revalidate,
1400
1404
  forceRefresh = false,
@@ -1572,7 +1576,6 @@ var VitalsCollector = class {
1572
1576
  tcp_connect: navEntry.connectEnd - navEntry.connectStart,
1573
1577
  request_time: navEntry.responseEnd - navEntry.requestStart,
1574
1578
  dom_load: navEntry.domComplete - navEntry.domInteractive,
1575
- // NEW: raw fields matching Rust NavigationTiming struct
1576
1579
  domain_lookup_start: navEntry.domainLookupStart,
1577
1580
  domain_lookup_end: navEntry.domainLookupEnd,
1578
1581
  connect_start: navEntry.connectStart,
@@ -1585,8 +1588,10 @@ var VitalsCollector = class {
1585
1588
  "resource"
1586
1589
  );
1587
1590
  if (resourceEntries.length > 0) {
1588
- this.metrics.resources = resourceEntries.filter((r) => !r.name.includes("/api/collect")).sort((a, b) => b.duration - a.duration).slice(0, 20).map((r) => ({
1589
- name: r.name,
1591
+ this.metrics.resources = resourceEntries.filter(
1592
+ (r) => !r.name.includes("/api/collect") && !r.name.includes("/analytics") && !r.name.includes("sentry.gnapex.com")
1593
+ ).sort((a, b) => b.duration - a.duration).slice(0, 5).map((r) => ({
1594
+ name: r.name.length > 120 ? r.name.substring(0, 120) + "..." : r.name,
1590
1595
  initiatorType: r.initiatorType,
1591
1596
  duration: Math.round(r.duration),
1592
1597
  transferSize: r.transferSize > 0 ? r.transferSize : void 0,
@@ -1618,7 +1623,7 @@ var VitalsCollector = class {
1618
1623
  var vitalsCollector = new VitalsCollector();
1619
1624
  var initVitals = (_tracker) => {
1620
1625
  if (process.env.NODE_ENV === "development") {
1621
- console.log("[NexusHub] Web Vitals monitoring active");
1626
+ console.log("[GN-Apex] Web Vitals monitoring active");
1622
1627
  }
1623
1628
  };
1624
1629
 
@@ -1771,7 +1776,8 @@ var Tracker = class {
1771
1776
  this.anonymousId = "";
1772
1777
  this.isFlushing = false;
1773
1778
  this.flushPromise = null;
1774
- this.batchSize = 25;
1779
+ // 🛡️ Batch size set to 10 to keep payloads strictly under Actix 32KB limit
1780
+ this.batchSize = 10;
1775
1781
  this.config = config;
1776
1782
  this.endpoint = `${this.config.analyticsUrl}/api/collect`;
1777
1783
  this.circuitBreaker = new CircuitBreaker();
@@ -1783,7 +1789,7 @@ var Tracker = class {
1783
1789
  }
1784
1790
  async initSession() {
1785
1791
  this.visitorId = await getVisitorId(
1786
- this.config.privacy?.fingerprinting ?? false
1792
+ this.config.privacy?.fingerprinting ?? true
1787
1793
  );
1788
1794
  let anonId = safeGetItem("nexus_anon_id");
1789
1795
  if (!anonId) {
@@ -1809,10 +1815,11 @@ var Tracker = class {
1809
1815
  if (typeof window === "undefined") return;
1810
1816
  safeSetItem("nexus_last_active", Date.now().toString());
1811
1817
  const entropy = await getDeviceEntropy(
1812
- this.config.privacy?.fingerprinting ?? false
1818
+ this.config.privacy?.fingerprinting ?? true
1813
1819
  );
1814
- const perfMetrics = vitalsCollector.getMetricsSnapshot();
1815
- const utmParams = extractUtmParams(window.location.href);
1820
+ const isPageView = eventType === "page_view" || eventType === "performance";
1821
+ const perfMetrics = isPageView ? vitalsCollector.getMetricsSnapshot() : void 0;
1822
+ const utmParams = isPageView ? extractUtmParams(window.location.href) : void 0;
1816
1823
  const payload = {
1817
1824
  projectId: this.config.projectId,
1818
1825
  sessionId: this.sessionId,
@@ -1821,10 +1828,9 @@ var Tracker = class {
1821
1828
  messageId: generateUUID(),
1822
1829
  sentAt: (/* @__PURE__ */ new Date()).toISOString(),
1823
1830
  version: SDK_VERSION,
1824
- // Dynamically synced to SDK 1.1.0
1825
1831
  url: window.location.href,
1826
- referrer: document.referrer,
1827
- userAgent: window.navigator.userAgent,
1832
+ referrer: isPageView ? document.referrer : void 0,
1833
+ userAgent: isPageView ? window.navigator.userAgent : void 0,
1828
1834
  screenWidth: window.screen.width,
1829
1835
  screenHeight: window.screen.height,
1830
1836
  language: window.navigator.language,
@@ -1887,6 +1893,10 @@ var Tracker = class {
1887
1893
  } catch {
1888
1894
  response = void 0;
1889
1895
  }
1896
+ if (response && response.status === 413) {
1897
+ await eventStorage.remove(storedEvents.map((e) => e.id));
1898
+ return;
1899
+ }
1890
1900
  if (!response || response.status === 404 || response.status === 405) {
1891
1901
  const results = await Promise.allSettled(
1892
1902
  payloads.map(
@@ -1899,7 +1909,7 @@ var Tracker = class {
1899
1909
  )
1900
1910
  );
1901
1911
  const successIds = results.flatMap(
1902
- (r, i) => r.status === "fulfilled" && r.value.ok ? [storedEvents[i].id] : []
1912
+ (r, i) => r.status === "fulfilled" && (r.value.ok || r.value.status === 413) ? [storedEvents[i].id] : []
1903
1913
  );
1904
1914
  if (successIds.length) await eventStorage.remove(successIds);
1905
1915
  if (successIds.length === storedEvents.length) {
package/dist/react.cjs CHANGED
@@ -865,7 +865,7 @@ var ContentEngine = class {
865
865
  );
866
866
  if (this.config.debug && duration > 100) {
867
867
  console.warn(
868
- `[NexusHub] \u26A0\uFE0F getPage("${slug}") took ${duration.toFixed(2)}ms`
868
+ `[GN-Apex] \u26A0\uFE0F getPage("${slug}") took ${duration.toFixed(2)}ms`
869
869
  );
870
870
  }
871
871
  return result;
@@ -902,7 +902,7 @@ var ContentEngine = class {
902
902
  }
903
903
  }
904
904
  if (this.circuitBreaker.isOpen()) {
905
- throw new Error("[NexusHub] Circuit open. API is unavailable.");
905
+ throw new Error("[GN-Apex] Circuit open. API is unavailable.");
906
906
  }
907
907
  try {
908
908
  await this.rateLimiter.checkLimit();
@@ -919,21 +919,22 @@ var ContentEngine = class {
919
919
  return includeMetadata ? data : data.data;
920
920
  } catch (error) {
921
921
  this.circuitBreaker.recordFailure();
922
- if (process.env.NODE_ENV === "development") {
923
- try {
924
- const local = await this.localCache.getPage(slug);
925
- if (local) {
926
- return includeMetadata ? {
927
- data: local,
928
- metadata: {
929
- timestamp: Date.now(),
930
- expiresAt: Infinity,
931
- tags: []
932
- }
933
- } : local;
934
- }
935
- } catch (e7) {
922
+ try {
923
+ const local = await this.localCache.getPage(slug);
924
+ if (local) {
925
+ console.warn(
926
+ `[GN-Apex] \u26A0\uFE0F Network timeout on '${slug}', successfully recovered from local cache.`
927
+ );
928
+ return includeMetadata ? {
929
+ data: local,
930
+ metadata: {
931
+ timestamp: Date.now(),
932
+ expiresAt: Infinity,
933
+ tags: []
934
+ }
935
+ } : local;
936
936
  }
937
+ } catch (e7) {
937
938
  }
938
939
  throw this.normalizeError(error, `Failed to fetch page '${slug}'`);
939
940
  }
@@ -962,17 +963,17 @@ var ContentEngine = class {
962
963
  localCollection,
963
964
  normalizedQuery
964
965
  );
965
- return result;
966
+ return includeMetadata ? result : result;
966
967
  }
967
968
  } catch (e8) {
968
969
  }
969
970
  }
970
971
  if (this.circuitBreaker.isOpen()) {
971
- throw new Error("[NexusHub] Circuit open. API is unavailable.");
972
+ throw new Error("[GN-Apex] Circuit open. API is unavailable.");
972
973
  }
973
974
  try {
974
975
  await this.rateLimiter.checkLimit();
975
- const result = await this.backoff.execute(async () => {
976
+ const entry = await this.backoff.execute(async () => {
976
977
  return this.fetchCollection(
977
978
  collectionId,
978
979
  normalizedQuery,
@@ -983,20 +984,22 @@ var ContentEngine = class {
983
984
  );
984
985
  });
985
986
  this.circuitBreaker.recordSuccess();
986
- return includeMetadata ? result : result.data;
987
+ return includeMetadata ? entry : entry.data;
987
988
  } catch (error) {
988
989
  this.circuitBreaker.recordFailure();
989
- if (process.env.NODE_ENV === "development") {
990
- try {
991
- const localCollection = await this.localCache.getCollection(collectionId);
992
- if (localCollection) {
993
- return this.applyLocalQuery(
994
- localCollection,
995
- normalizedQuery
996
- );
997
- }
998
- } catch (e9) {
990
+ try {
991
+ const localCollection = await this.localCache.getCollection(collectionId);
992
+ if (localCollection) {
993
+ console.warn(
994
+ `[GN-Apex] \u26A0\uFE0F Network timeout on '${collectionId}', successfully recovered from local cache.`
995
+ );
996
+ const result = this.applyLocalQuery(
997
+ localCollection,
998
+ normalizedQuery
999
+ );
1000
+ return includeMetadata ? result : result;
999
1001
  }
1002
+ } catch (e9) {
1000
1003
  }
1001
1004
  throw this.normalizeError(
1002
1005
  error,
@@ -1055,14 +1058,15 @@ var ContentEngine = class {
1055
1058
  }
1056
1059
  return data;
1057
1060
  } catch (error) {
1058
- if (process.env.NODE_ENV === "development") {
1059
- try {
1060
- const localGlobals = await this.localCache.getGlobals();
1061
- if (localGlobals) {
1062
- return localGlobals;
1063
- }
1064
- } catch (e11) {
1061
+ try {
1062
+ const localGlobals = await this.localCache.getGlobals();
1063
+ if (localGlobals) {
1064
+ console.warn(
1065
+ `[GN-Apex] \u26A0\uFE0F Network timeout on globals, successfully recovered from local cache.`
1066
+ );
1067
+ return localGlobals;
1065
1068
  }
1069
+ } catch (e11) {
1066
1070
  }
1067
1071
  throw this.normalizeError(error, "Failed to fetch globals");
1068
1072
  }
@@ -1213,7 +1217,7 @@ var ContentEngine = class {
1213
1217
  };
1214
1218
  }
1215
1219
  writeCache(key, data, options) {
1216
- const ttlSeconds = options.revalidate === false ? 60 : Math.max(1, options.revalidate);
1220
+ const ttlSeconds = options.revalidate === false ? 5 : Math.max(1, options.revalidate);
1217
1221
  if (this.cacheStrategy === "memory") {
1218
1222
  this.memoryCache.set(key, data, {
1219
1223
  tags: options.tags,
@@ -1376,7 +1380,7 @@ var ContentEngine = class {
1376
1380
  }
1377
1381
  async fetchWithTimeout(url, options = {}) {
1378
1382
  const {
1379
- timeout = this.config.timeout || 1e4,
1383
+ timeout = this.config.timeout || 25e3,
1380
1384
  tags = [],
1381
1385
  revalidate,
1382
1386
  forceRefresh = false,
@@ -1551,7 +1555,6 @@ var VitalsCollector = class {
1551
1555
  tcp_connect: navEntry.connectEnd - navEntry.connectStart,
1552
1556
  request_time: navEntry.responseEnd - navEntry.requestStart,
1553
1557
  dom_load: navEntry.domComplete - navEntry.domInteractive,
1554
- // NEW: raw fields matching Rust NavigationTiming struct
1555
1558
  domain_lookup_start: navEntry.domainLookupStart,
1556
1559
  domain_lookup_end: navEntry.domainLookupEnd,
1557
1560
  connect_start: navEntry.connectStart,
@@ -1564,8 +1567,10 @@ var VitalsCollector = class {
1564
1567
  "resource"
1565
1568
  );
1566
1569
  if (resourceEntries.length > 0) {
1567
- this.metrics.resources = resourceEntries.filter((r) => !r.name.includes("/api/collect")).sort((a, b) => b.duration - a.duration).slice(0, 20).map((r) => ({
1568
- name: r.name,
1570
+ this.metrics.resources = resourceEntries.filter(
1571
+ (r) => !r.name.includes("/api/collect") && !r.name.includes("/analytics") && !r.name.includes("sentry.gnapex.com")
1572
+ ).sort((a, b) => b.duration - a.duration).slice(0, 5).map((r) => ({
1573
+ name: r.name.length > 120 ? r.name.substring(0, 120) + "..." : r.name,
1569
1574
  initiatorType: r.initiatorType,
1570
1575
  duration: Math.round(r.duration),
1571
1576
  transferSize: r.transferSize > 0 ? r.transferSize : void 0,
@@ -1597,7 +1602,7 @@ var VitalsCollector = class {
1597
1602
  var vitalsCollector = new VitalsCollector();
1598
1603
  var initVitals = (_tracker) => {
1599
1604
  if (process.env.NODE_ENV === "development") {
1600
- console.log("[NexusHub] Web Vitals monitoring active");
1605
+ console.log("[GN-Apex] Web Vitals monitoring active");
1601
1606
  }
1602
1607
  };
1603
1608
 
@@ -1750,7 +1755,8 @@ var Tracker = class {
1750
1755
  this.anonymousId = "";
1751
1756
  this.isFlushing = false;
1752
1757
  this.flushPromise = null;
1753
- this.batchSize = 25;
1758
+ // 🛡️ Batch size set to 10 to keep payloads strictly under Actix 32KB limit
1759
+ this.batchSize = 10;
1754
1760
  this.config = config;
1755
1761
  this.endpoint = `${this.config.analyticsUrl}/api/collect`;
1756
1762
  this.circuitBreaker = new CircuitBreaker();
@@ -1762,7 +1768,7 @@ var Tracker = class {
1762
1768
  }
1763
1769
  async initSession() {
1764
1770
  this.visitorId = await getVisitorId(
1765
- _nullishCoalesce(_optionalChain([this, 'access', _27 => _27.config, 'access', _28 => _28.privacy, 'optionalAccess', _29 => _29.fingerprinting]), () => ( false))
1771
+ _nullishCoalesce(_optionalChain([this, 'access', _27 => _27.config, 'access', _28 => _28.privacy, 'optionalAccess', _29 => _29.fingerprinting]), () => ( true))
1766
1772
  );
1767
1773
  let anonId = safeGetItem("nexus_anon_id");
1768
1774
  if (!anonId) {
@@ -1788,10 +1794,11 @@ var Tracker = class {
1788
1794
  if (typeof window === "undefined") return;
1789
1795
  safeSetItem("nexus_last_active", Date.now().toString());
1790
1796
  const entropy = await getDeviceEntropy(
1791
- _nullishCoalesce(_optionalChain([this, 'access', _30 => _30.config, 'access', _31 => _31.privacy, 'optionalAccess', _32 => _32.fingerprinting]), () => ( false))
1797
+ _nullishCoalesce(_optionalChain([this, 'access', _30 => _30.config, 'access', _31 => _31.privacy, 'optionalAccess', _32 => _32.fingerprinting]), () => ( true))
1792
1798
  );
1793
- const perfMetrics = vitalsCollector.getMetricsSnapshot();
1794
- const utmParams = extractUtmParams(window.location.href);
1799
+ const isPageView = eventType === "page_view" || eventType === "performance";
1800
+ const perfMetrics = isPageView ? vitalsCollector.getMetricsSnapshot() : void 0;
1801
+ const utmParams = isPageView ? extractUtmParams(window.location.href) : void 0;
1795
1802
  const payload = {
1796
1803
  projectId: this.config.projectId,
1797
1804
  sessionId: this.sessionId,
@@ -1800,10 +1807,9 @@ var Tracker = class {
1800
1807
  messageId: generateUUID(),
1801
1808
  sentAt: (/* @__PURE__ */ new Date()).toISOString(),
1802
1809
  version: _chunkOP3LNZPCcjs.SDK_VERSION,
1803
- // Dynamically synced to SDK 1.1.0
1804
1810
  url: window.location.href,
1805
- referrer: document.referrer,
1806
- userAgent: window.navigator.userAgent,
1811
+ referrer: isPageView ? document.referrer : void 0,
1812
+ userAgent: isPageView ? window.navigator.userAgent : void 0,
1807
1813
  screenWidth: window.screen.width,
1808
1814
  screenHeight: window.screen.height,
1809
1815
  language: window.navigator.language,
@@ -1866,6 +1872,10 @@ var Tracker = class {
1866
1872
  } catch (e17) {
1867
1873
  response = void 0;
1868
1874
  }
1875
+ if (response && response.status === 413) {
1876
+ await eventStorage.remove(storedEvents.map((e) => e.id));
1877
+ return;
1878
+ }
1869
1879
  if (!response || response.status === 404 || response.status === 405) {
1870
1880
  const results = await Promise.allSettled(
1871
1881
  payloads.map(
@@ -1878,7 +1888,7 @@ var Tracker = class {
1878
1888
  )
1879
1889
  );
1880
1890
  const successIds = results.flatMap(
1881
- (r, i) => r.status === "fulfilled" && r.value.ok ? [storedEvents[i].id] : []
1891
+ (r, i) => r.status === "fulfilled" && (r.value.ok || r.value.status === 413) ? [storedEvents[i].id] : []
1882
1892
  );
1883
1893
  if (successIds.length) await eventStorage.remove(successIds);
1884
1894
  if (successIds.length === storedEvents.length) {
package/dist/react.js CHANGED
@@ -865,7 +865,7 @@ var ContentEngine = class {
865
865
  );
866
866
  if (this.config.debug && duration > 100) {
867
867
  console.warn(
868
- `[NexusHub] \u26A0\uFE0F getPage("${slug}") took ${duration.toFixed(2)}ms`
868
+ `[GN-Apex] \u26A0\uFE0F getPage("${slug}") took ${duration.toFixed(2)}ms`
869
869
  );
870
870
  }
871
871
  return result;
@@ -902,7 +902,7 @@ var ContentEngine = class {
902
902
  }
903
903
  }
904
904
  if (this.circuitBreaker.isOpen()) {
905
- throw new Error("[NexusHub] Circuit open. API is unavailable.");
905
+ throw new Error("[GN-Apex] Circuit open. API is unavailable.");
906
906
  }
907
907
  try {
908
908
  await this.rateLimiter.checkLimit();
@@ -919,21 +919,22 @@ var ContentEngine = class {
919
919
  return includeMetadata ? data : data.data;
920
920
  } catch (error) {
921
921
  this.circuitBreaker.recordFailure();
922
- if (process.env.NODE_ENV === "development") {
923
- try {
924
- const local = await this.localCache.getPage(slug);
925
- if (local) {
926
- return includeMetadata ? {
927
- data: local,
928
- metadata: {
929
- timestamp: Date.now(),
930
- expiresAt: Infinity,
931
- tags: []
932
- }
933
- } : local;
934
- }
935
- } catch {
922
+ try {
923
+ const local = await this.localCache.getPage(slug);
924
+ if (local) {
925
+ console.warn(
926
+ `[GN-Apex] \u26A0\uFE0F Network timeout on '${slug}', successfully recovered from local cache.`
927
+ );
928
+ return includeMetadata ? {
929
+ data: local,
930
+ metadata: {
931
+ timestamp: Date.now(),
932
+ expiresAt: Infinity,
933
+ tags: []
934
+ }
935
+ } : local;
936
936
  }
937
+ } catch {
937
938
  }
938
939
  throw this.normalizeError(error, `Failed to fetch page '${slug}'`);
939
940
  }
@@ -962,17 +963,17 @@ var ContentEngine = class {
962
963
  localCollection,
963
964
  normalizedQuery
964
965
  );
965
- return result;
966
+ return includeMetadata ? result : result;
966
967
  }
967
968
  } catch {
968
969
  }
969
970
  }
970
971
  if (this.circuitBreaker.isOpen()) {
971
- throw new Error("[NexusHub] Circuit open. API is unavailable.");
972
+ throw new Error("[GN-Apex] Circuit open. API is unavailable.");
972
973
  }
973
974
  try {
974
975
  await this.rateLimiter.checkLimit();
975
- const result = await this.backoff.execute(async () => {
976
+ const entry = await this.backoff.execute(async () => {
976
977
  return this.fetchCollection(
977
978
  collectionId,
978
979
  normalizedQuery,
@@ -983,20 +984,22 @@ var ContentEngine = class {
983
984
  );
984
985
  });
985
986
  this.circuitBreaker.recordSuccess();
986
- return includeMetadata ? result : result.data;
987
+ return includeMetadata ? entry : entry.data;
987
988
  } catch (error) {
988
989
  this.circuitBreaker.recordFailure();
989
- if (process.env.NODE_ENV === "development") {
990
- try {
991
- const localCollection = await this.localCache.getCollection(collectionId);
992
- if (localCollection) {
993
- return this.applyLocalQuery(
994
- localCollection,
995
- normalizedQuery
996
- );
997
- }
998
- } catch {
990
+ try {
991
+ const localCollection = await this.localCache.getCollection(collectionId);
992
+ if (localCollection) {
993
+ console.warn(
994
+ `[GN-Apex] \u26A0\uFE0F Network timeout on '${collectionId}', successfully recovered from local cache.`
995
+ );
996
+ const result = this.applyLocalQuery(
997
+ localCollection,
998
+ normalizedQuery
999
+ );
1000
+ return includeMetadata ? result : result;
999
1001
  }
1002
+ } catch {
1000
1003
  }
1001
1004
  throw this.normalizeError(
1002
1005
  error,
@@ -1055,14 +1058,15 @@ var ContentEngine = class {
1055
1058
  }
1056
1059
  return data;
1057
1060
  } catch (error) {
1058
- if (process.env.NODE_ENV === "development") {
1059
- try {
1060
- const localGlobals = await this.localCache.getGlobals();
1061
- if (localGlobals) {
1062
- return localGlobals;
1063
- }
1064
- } catch {
1061
+ try {
1062
+ const localGlobals = await this.localCache.getGlobals();
1063
+ if (localGlobals) {
1064
+ console.warn(
1065
+ `[GN-Apex] \u26A0\uFE0F Network timeout on globals, successfully recovered from local cache.`
1066
+ );
1067
+ return localGlobals;
1065
1068
  }
1069
+ } catch {
1066
1070
  }
1067
1071
  throw this.normalizeError(error, "Failed to fetch globals");
1068
1072
  }
@@ -1213,7 +1217,7 @@ var ContentEngine = class {
1213
1217
  };
1214
1218
  }
1215
1219
  writeCache(key, data, options) {
1216
- const ttlSeconds = options.revalidate === false ? 60 : Math.max(1, options.revalidate);
1220
+ const ttlSeconds = options.revalidate === false ? 5 : Math.max(1, options.revalidate);
1217
1221
  if (this.cacheStrategy === "memory") {
1218
1222
  this.memoryCache.set(key, data, {
1219
1223
  tags: options.tags,
@@ -1376,7 +1380,7 @@ var ContentEngine = class {
1376
1380
  }
1377
1381
  async fetchWithTimeout(url, options = {}) {
1378
1382
  const {
1379
- timeout = this.config.timeout || 1e4,
1383
+ timeout = this.config.timeout || 25e3,
1380
1384
  tags = [],
1381
1385
  revalidate,
1382
1386
  forceRefresh = false,
@@ -1551,7 +1555,6 @@ var VitalsCollector = class {
1551
1555
  tcp_connect: navEntry.connectEnd - navEntry.connectStart,
1552
1556
  request_time: navEntry.responseEnd - navEntry.requestStart,
1553
1557
  dom_load: navEntry.domComplete - navEntry.domInteractive,
1554
- // NEW: raw fields matching Rust NavigationTiming struct
1555
1558
  domain_lookup_start: navEntry.domainLookupStart,
1556
1559
  domain_lookup_end: navEntry.domainLookupEnd,
1557
1560
  connect_start: navEntry.connectStart,
@@ -1564,8 +1567,10 @@ var VitalsCollector = class {
1564
1567
  "resource"
1565
1568
  );
1566
1569
  if (resourceEntries.length > 0) {
1567
- this.metrics.resources = resourceEntries.filter((r) => !r.name.includes("/api/collect")).sort((a, b) => b.duration - a.duration).slice(0, 20).map((r) => ({
1568
- name: r.name,
1570
+ this.metrics.resources = resourceEntries.filter(
1571
+ (r) => !r.name.includes("/api/collect") && !r.name.includes("/analytics") && !r.name.includes("sentry.gnapex.com")
1572
+ ).sort((a, b) => b.duration - a.duration).slice(0, 5).map((r) => ({
1573
+ name: r.name.length > 120 ? r.name.substring(0, 120) + "..." : r.name,
1569
1574
  initiatorType: r.initiatorType,
1570
1575
  duration: Math.round(r.duration),
1571
1576
  transferSize: r.transferSize > 0 ? r.transferSize : void 0,
@@ -1597,7 +1602,7 @@ var VitalsCollector = class {
1597
1602
  var vitalsCollector = new VitalsCollector();
1598
1603
  var initVitals = (_tracker) => {
1599
1604
  if (process.env.NODE_ENV === "development") {
1600
- console.log("[NexusHub] Web Vitals monitoring active");
1605
+ console.log("[GN-Apex] Web Vitals monitoring active");
1601
1606
  }
1602
1607
  };
1603
1608
 
@@ -1750,7 +1755,8 @@ var Tracker = class {
1750
1755
  this.anonymousId = "";
1751
1756
  this.isFlushing = false;
1752
1757
  this.flushPromise = null;
1753
- this.batchSize = 25;
1758
+ // 🛡️ Batch size set to 10 to keep payloads strictly under Actix 32KB limit
1759
+ this.batchSize = 10;
1754
1760
  this.config = config;
1755
1761
  this.endpoint = `${this.config.analyticsUrl}/api/collect`;
1756
1762
  this.circuitBreaker = new CircuitBreaker();
@@ -1762,7 +1768,7 @@ var Tracker = class {
1762
1768
  }
1763
1769
  async initSession() {
1764
1770
  this.visitorId = await getVisitorId(
1765
- this.config.privacy?.fingerprinting ?? false
1771
+ this.config.privacy?.fingerprinting ?? true
1766
1772
  );
1767
1773
  let anonId = safeGetItem("nexus_anon_id");
1768
1774
  if (!anonId) {
@@ -1788,10 +1794,11 @@ var Tracker = class {
1788
1794
  if (typeof window === "undefined") return;
1789
1795
  safeSetItem("nexus_last_active", Date.now().toString());
1790
1796
  const entropy = await getDeviceEntropy(
1791
- this.config.privacy?.fingerprinting ?? false
1797
+ this.config.privacy?.fingerprinting ?? true
1792
1798
  );
1793
- const perfMetrics = vitalsCollector.getMetricsSnapshot();
1794
- const utmParams = extractUtmParams(window.location.href);
1799
+ const isPageView = eventType === "page_view" || eventType === "performance";
1800
+ const perfMetrics = isPageView ? vitalsCollector.getMetricsSnapshot() : void 0;
1801
+ const utmParams = isPageView ? extractUtmParams(window.location.href) : void 0;
1795
1802
  const payload = {
1796
1803
  projectId: this.config.projectId,
1797
1804
  sessionId: this.sessionId,
@@ -1800,10 +1807,9 @@ var Tracker = class {
1800
1807
  messageId: generateUUID(),
1801
1808
  sentAt: (/* @__PURE__ */ new Date()).toISOString(),
1802
1809
  version: SDK_VERSION,
1803
- // Dynamically synced to SDK 1.1.0
1804
1810
  url: window.location.href,
1805
- referrer: document.referrer,
1806
- userAgent: window.navigator.userAgent,
1811
+ referrer: isPageView ? document.referrer : void 0,
1812
+ userAgent: isPageView ? window.navigator.userAgent : void 0,
1807
1813
  screenWidth: window.screen.width,
1808
1814
  screenHeight: window.screen.height,
1809
1815
  language: window.navigator.language,
@@ -1866,6 +1872,10 @@ var Tracker = class {
1866
1872
  } catch {
1867
1873
  response = void 0;
1868
1874
  }
1875
+ if (response && response.status === 413) {
1876
+ await eventStorage.remove(storedEvents.map((e) => e.id));
1877
+ return;
1878
+ }
1869
1879
  if (!response || response.status === 404 || response.status === 405) {
1870
1880
  const results = await Promise.allSettled(
1871
1881
  payloads.map(
@@ -1878,7 +1888,7 @@ var Tracker = class {
1878
1888
  )
1879
1889
  );
1880
1890
  const successIds = results.flatMap(
1881
- (r, i) => r.status === "fulfilled" && r.value.ok ? [storedEvents[i].id] : []
1891
+ (r, i) => r.status === "fulfilled" && (r.value.ok || r.value.status === 413) ? [storedEvents[i].id] : []
1882
1892
  );
1883
1893
  if (successIds.length) await eventStorage.remove(successIds);
1884
1894
  if (successIds.length === storedEvents.length) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nexushub/client",
3
3
  "private": false,
4
- "version": "1.1.8",
4
+ "version": "1.1.11",
5
5
  "description": "GN-Apex zero-config production runtime SDK",
6
6
  "type": "module",
7
7
  "main": "./dist/index.cjs",