@nexushub/client 0.1.2 → 0.1.3

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
@@ -365,7 +365,9 @@ var RateLimiter = class {
365
365
  getStats() {
366
366
  const now = Date.now();
367
367
  const windowStart = now - this.config.timeWindow;
368
- const currentRequests = this.requests.filter((time) => time > windowStart).length;
368
+ const currentRequests = this.requests.filter(
369
+ (time) => time > windowStart
370
+ ).length;
369
371
  return {
370
372
  currentRequests,
371
373
  limit: this.config.maxRequests
@@ -446,10 +448,15 @@ var CircuitBreaker = class {
446
448
  if (this.failures >= this.failureThreshold) {
447
449
  this.state = 1 /* OPEN */;
448
450
  if (process.env.NODE_ENV === "development") {
449
- console.warn(`[NexusHub] \u{1F50C} Circuit Breaker OPEN. Pausing network requests.`);
451
+ console.warn(
452
+ `[NexusHub] \u{1F50C} Circuit Breaker OPEN. Pausing network requests.`
453
+ );
450
454
  }
451
455
  }
452
456
  }
457
+ isIgnorableError(error) {
458
+ return _optionalChain([error, 'optionalAccess', _13 => _13.status]) === 401 || _optionalChain([error, 'optionalAccess', _14 => _14.status]) === 404;
459
+ }
453
460
  };
454
461
  var RequestBatcher = class {
455
462
  constructor(batchWindow = 10, maxBatchSize = 20) {
@@ -527,10 +534,10 @@ function buildQueryString(query) {
527
534
  if (query.sort) params.append("sort", query.sort);
528
535
  if (query.order) params.append("order", query.order);
529
536
  if (query.search) params.append("search", query.search);
530
- if (_optionalChain([query, 'access', _13 => _13.include, 'optionalAccess', _14 => _14.length])) {
537
+ if (_optionalChain([query, 'access', _15 => _15.include, 'optionalAccess', _16 => _16.length])) {
531
538
  params.append("include", query.include.join(","));
532
539
  }
533
- if (_optionalChain([query, 'access', _15 => _15.fields, 'optionalAccess', _16 => _16.length])) {
540
+ if (_optionalChain([query, 'access', _17 => _17.fields, 'optionalAccess', _18 => _18.length])) {
534
541
  params.append("fields", query.fields.join(","));
535
542
  }
536
543
  if (query.filter) {
@@ -812,7 +819,7 @@ var ContentEngine = class {
812
819
  }
813
820
  return this.requestBatcher.schedule(cacheKey, async () => {
814
821
  const params = new URLSearchParams();
815
- if (_optionalChain([options, 'access', _17 => _17.include, 'optionalAccess', _18 => _18.length])) {
822
+ if (_optionalChain([options, 'access', _19 => _19.include, 'optionalAccess', _20 => _20.length])) {
816
823
  params.append("include", options.include.join(","));
817
824
  }
818
825
  const url = `${this.config.apiUrl}/content/${this.config.projectId}/collection/${collectionId}/${itemId}?${params}`;
@@ -845,10 +852,10 @@ var ContentEngine = class {
845
852
  q: query,
846
853
  limit: (options.limit || 20).toString()
847
854
  });
848
- if (_optionalChain([options, 'access', _19 => _19.collections, 'optionalAccess', _20 => _20.length])) {
855
+ if (_optionalChain([options, 'access', _21 => _21.collections, 'optionalAccess', _22 => _22.length])) {
849
856
  params.append("collections", options.collections.join(","));
850
857
  }
851
- if (_optionalChain([options, 'access', _21 => _21.fields, 'optionalAccess', _22 => _22.length])) {
858
+ if (_optionalChain([options, 'access', _23 => _23.fields, 'optionalAccess', _24 => _24.length])) {
852
859
  params.append("fields", options.fields.join(","));
853
860
  }
854
861
  const url = `${this.config.apiUrl}/content/${this.config.projectId}/search?${params}`;
@@ -909,7 +916,7 @@ var ContentEngine = class {
909
916
  }
910
917
  };
911
918
  eventSource.onerror = () => {
912
- _optionalChain([eventSource, 'optionalAccess', _23 => _23.close, 'call', _24 => _24()]);
919
+ _optionalChain([eventSource, 'optionalAccess', _25 => _25.close, 'call', _26 => _26()]);
913
920
  if (isClosed) return;
914
921
  const timeout = Math.min(1e3 * Math.pow(2, retryCount), 1e4);
915
922
  retryCount++;
@@ -922,7 +929,7 @@ var ContentEngine = class {
922
929
  connect();
923
930
  return () => {
924
931
  isClosed = true;
925
- _optionalChain([eventSource, 'optionalAccess', _25 => _25.close, 'call', _26 => _26()]);
932
+ _optionalChain([eventSource, 'optionalAccess', _27 => _27.close, 'call', _28 => _28()]);
926
933
  };
927
934
  }
928
935
  // --- CACHE MANAGEMENT ---
@@ -1462,34 +1469,31 @@ var Tracker = class {
1462
1469
  const entropy = await getDeviceEntropy();
1463
1470
  const perfMetrics = vitalsCollector.getMetricsSnapshot();
1464
1471
  const payload = {
1465
- project_id: this.config.projectId,
1466
- session_id: this.sessionId,
1467
- // We send this, Rust verifies it
1472
+ projectId: this.config.projectId,
1473
+ sessionId: this.sessionId,
1468
1474
  url: window.location.href,
1469
1475
  referrer: document.referrer,
1470
- user_agent: window.navigator.userAgent,
1471
- screen_width: window.screen.width,
1472
- screen_height: window.screen.height,
1476
+ userAgent: window.navigator.userAgent,
1477
+ screenWidth: window.screen.width,
1478
+ screenHeight: window.screen.height,
1473
1479
  language: window.navigator.language,
1474
1480
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
1475
- event_type: eventType,
1476
- event_name: eventName,
1477
- event_data: data,
1478
- // 3. Attach Performance Data (Rust: Option<PerformanceMetrics>)
1481
+ eventType,
1482
+ eventName,
1483
+ eventData: data,
1479
1484
  performance: perfMetrics || void 0,
1480
- // 4. Attach Hardware Signals for Anomaly Detection (Rust: DeviceData)
1481
1485
  context: {
1482
1486
  device: {
1483
- hardware_concurrency: entropy.hardware_concurrency,
1484
- device_memory: entropy.device_memory,
1485
- pixel_ratio: entropy.pixel_ratio,
1486
- canvas_fingerprint: entropy.canvas_hash,
1487
+ hardwareConcurrency: entropy.hardware_concurrency,
1488
+ // Match Rust sub-struct too if needed
1489
+ deviceMemory: entropy.device_memory,
1490
+ pixelRatio: entropy.pixel_ratio,
1491
+ canvasFingerprint: entropy.canvas_hash,
1487
1492
  platform: entropy.platform
1488
1493
  },
1489
- visitor_id_local: this.visitorId
1490
- // Hint for stitching
1494
+ visitorIdLocal: this.visitorId
1491
1495
  },
1492
- client_timestamp: (/* @__PURE__ */ new Date()).toISOString()
1496
+ clientTimestamp: (/* @__PURE__ */ new Date()).toISOString()
1493
1497
  };
1494
1498
  await eventStorage.enqueue(payload);
1495
1499
  const count = await eventStorage.count();
@@ -1611,8 +1615,8 @@ var AnalyticsEngine = class {
1611
1615
  navigator.share = (data) => {
1612
1616
  this.tracker.send("social_share", {
1613
1617
  method: "native_share_menu",
1614
- url: _optionalChain([data, 'optionalAccess', _27 => _27.url]) || window.location.href,
1615
- title: _optionalChain([data, 'optionalAccess', _28 => _28.title])
1618
+ url: _optionalChain([data, 'optionalAccess', _29 => _29.url]) || window.location.href,
1619
+ title: _optionalChain([data, 'optionalAccess', _30 => _30.title])
1616
1620
  });
1617
1621
  return originalShare.apply(navigator, [data]);
1618
1622
  };
@@ -1707,9 +1711,9 @@ var AnalyticsEngine = class {
1707
1711
  const config = this.tracker["config"];
1708
1712
  const endpoint = `${config.analyticsUrl}/api/${type}`;
1709
1713
  const payload = {
1710
- project_id: this.tracker["config"].projectId,
1711
- session_id: this.tracker.getSession(),
1712
- visitor_id: this.tracker.visitorId,
1714
+ projectId: config.projectId,
1715
+ sessionId: this.tracker.getSession(),
1716
+ visitorId: this.tracker.visitorId,
1713
1717
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1714
1718
  ...data
1715
1719
  };
@@ -1743,7 +1747,7 @@ var AnalyticsEngine = class {
1743
1747
  this.tracker.send("click", {
1744
1748
  element_type: "link",
1745
1749
  href: link.href,
1746
- text: _optionalChain([link, 'access', _29 => _29.innerText, 'optionalAccess', _30 => _30.substring, 'call', _31 => _31(0, 50)]),
1750
+ text: _optionalChain([link, 'access', _31 => _31.innerText, 'optionalAccess', _32 => _32.substring, 'call', _33 => _33(0, 50)]),
1747
1751
  id: link.id,
1748
1752
  classes: link.className,
1749
1753
  dataset: { ...link.dataset }
@@ -1753,7 +1757,7 @@ var AnalyticsEngine = class {
1753
1757
  if (button) {
1754
1758
  this.tracker.send("click", {
1755
1759
  element_type: "button",
1756
- text: _optionalChain([button, 'access', _32 => _32.innerText, 'optionalAccess', _33 => _33.substring, 'call', _34 => _34(0, 50)]),
1760
+ text: _optionalChain([button, 'access', _34 => _34.innerText, 'optionalAccess', _35 => _35.substring, 'call', _36 => _36(0, 50)]),
1757
1761
  id: button.id,
1758
1762
  classes: button.className,
1759
1763
  coordinates: { x: e.clientX, y: e.clientY }
@@ -1823,11 +1827,11 @@ var NexusClient = class {
1823
1827
  constructor(config) {
1824
1828
  const fullConfig = getFullConfig(config);
1825
1829
  this.config = {
1826
- debug: _optionalChain([config, 'optionalAccess', _35 => _35.debug]) || false,
1827
- cacheStrategy: _optionalChain([config, 'optionalAccess', _36 => _36.cacheStrategy]) || "memory",
1828
- revalidateTime: _optionalChain([config, 'optionalAccess', _37 => _37.revalidateTime]) || 60,
1829
- timeout: _optionalChain([config, 'optionalAccess', _38 => _38.timeout]) || 1e4,
1830
- retries: _optionalChain([config, 'optionalAccess', _39 => _39.retries]) || 3,
1830
+ debug: _optionalChain([config, 'optionalAccess', _37 => _37.debug]) || false,
1831
+ cacheStrategy: _optionalChain([config, 'optionalAccess', _38 => _38.cacheStrategy]) || "memory",
1832
+ revalidateTime: _optionalChain([config, 'optionalAccess', _39 => _39.revalidateTime]) || 60,
1833
+ timeout: _optionalChain([config, 'optionalAccess', _40 => _40.timeout]) || 1e4,
1834
+ retries: _optionalChain([config, 'optionalAccess', _41 => _41.retries]) || 3,
1831
1835
  ...fullConfig
1832
1836
  };
1833
1837
  this.content = new ContentEngine(this.config);
@@ -1862,6 +1866,12 @@ var _navigation = require('next/navigation');
1862
1866
 
1863
1867
  // src/auth/context.tsx
1864
1868
 
1869
+
1870
+
1871
+
1872
+
1873
+
1874
+
1865
1875
  var _jsxruntime = require('react/jsx-runtime');
1866
1876
  var AuthContext = _react.createContext.call(void 0, null);
1867
1877
  var AuthProvider = ({
@@ -1957,7 +1967,10 @@ var AuthProvider = ({
1957
1967
  const logout = async () => {
1958
1968
  setIsLoading(true);
1959
1969
  try {
1960
- await fetch(`${AUTH_BASE}/logout`, { method: "POST", headers: getHeaders(config) });
1970
+ await fetch(`${AUTH_BASE}/logout`, {
1971
+ method: "POST",
1972
+ headers: getHeaders(config)
1973
+ });
1961
1974
  } catch (e) {
1962
1975
  console.warn("Logout network error", e);
1963
1976
  } finally {
@@ -1994,17 +2007,23 @@ var AuthProvider = ({
1994
2007
  });
1995
2008
  if (!res.ok) throw await parseError(res);
1996
2009
  };
1997
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AuthContext.Provider, { value: {
1998
- user,
1999
- isLoading,
2000
- error,
2001
- isAuthenticated: !!user,
2002
- login,
2003
- register,
2004
- logout,
2005
- updateProfile,
2006
- requestPasswordReset
2007
- }, children });
2010
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2011
+ AuthContext.Provider,
2012
+ {
2013
+ value: {
2014
+ user,
2015
+ isLoading,
2016
+ error,
2017
+ isAuthenticated: !!user,
2018
+ login,
2019
+ register,
2020
+ logout,
2021
+ updateProfile,
2022
+ requestPasswordReset
2023
+ },
2024
+ children
2025
+ }
2026
+ );
2008
2027
  };
2009
2028
  var useNexusAuth = () => {
2010
2029
  const context = _react.useContext.call(void 0, AuthContext);
@@ -2016,8 +2035,10 @@ var useNexusAuth = () => {
2016
2035
  function getHeaders(config) {
2017
2036
  return {
2018
2037
  "Content-Type": "application/json",
2019
- "x-nexus-project": config.projectId
2020
- // Note: We do NOT send the Master API Key here.
2038
+ "x-nexus-project": config.projectId,
2039
+ Authorization: `Bearer ${config.apiKey}`
2040
+ // 👈 CRITICAL: Send the nx_pk_ key
2041
+ // Note: We do NOT send the Master API Key here.
2021
2042
  // This is client-side. The backend uses Cookies or public tokens.
2022
2043
  };
2023
2044
  }
package/dist/index.d.cts CHANGED
@@ -325,7 +325,7 @@ interface AuthContextType extends AuthState {
325
325
  requestPasswordReset: (email: string) => Promise<void>;
326
326
  }
327
327
 
328
- declare const AuthProvider: ({ children, config }: {
328
+ declare const AuthProvider: ({ children, config, }: {
329
329
  children: React.ReactNode;
330
330
  config: NexusConfig;
331
331
  }) => react_jsx_runtime.JSX.Element;
package/dist/index.d.ts CHANGED
@@ -325,7 +325,7 @@ interface AuthContextType extends AuthState {
325
325
  requestPasswordReset: (email: string) => Promise<void>;
326
326
  }
327
327
 
328
- declare const AuthProvider: ({ children, config }: {
328
+ declare const AuthProvider: ({ children, config, }: {
329
329
  children: React.ReactNode;
330
330
  config: NexusConfig;
331
331
  }) => react_jsx_runtime.JSX.Element;
package/dist/index.js CHANGED
@@ -365,7 +365,9 @@ var RateLimiter = class {
365
365
  getStats() {
366
366
  const now = Date.now();
367
367
  const windowStart = now - this.config.timeWindow;
368
- const currentRequests = this.requests.filter((time) => time > windowStart).length;
368
+ const currentRequests = this.requests.filter(
369
+ (time) => time > windowStart
370
+ ).length;
369
371
  return {
370
372
  currentRequests,
371
373
  limit: this.config.maxRequests
@@ -446,10 +448,15 @@ var CircuitBreaker = class {
446
448
  if (this.failures >= this.failureThreshold) {
447
449
  this.state = 1 /* OPEN */;
448
450
  if (process.env.NODE_ENV === "development") {
449
- console.warn(`[NexusHub] \u{1F50C} Circuit Breaker OPEN. Pausing network requests.`);
451
+ console.warn(
452
+ `[NexusHub] \u{1F50C} Circuit Breaker OPEN. Pausing network requests.`
453
+ );
450
454
  }
451
455
  }
452
456
  }
457
+ isIgnorableError(error) {
458
+ return error?.status === 401 || error?.status === 404;
459
+ }
453
460
  };
454
461
  var RequestBatcher = class {
455
462
  constructor(batchWindow = 10, maxBatchSize = 20) {
@@ -1462,34 +1469,31 @@ var Tracker = class {
1462
1469
  const entropy = await getDeviceEntropy();
1463
1470
  const perfMetrics = vitalsCollector.getMetricsSnapshot();
1464
1471
  const payload = {
1465
- project_id: this.config.projectId,
1466
- session_id: this.sessionId,
1467
- // We send this, Rust verifies it
1472
+ projectId: this.config.projectId,
1473
+ sessionId: this.sessionId,
1468
1474
  url: window.location.href,
1469
1475
  referrer: document.referrer,
1470
- user_agent: window.navigator.userAgent,
1471
- screen_width: window.screen.width,
1472
- screen_height: window.screen.height,
1476
+ userAgent: window.navigator.userAgent,
1477
+ screenWidth: window.screen.width,
1478
+ screenHeight: window.screen.height,
1473
1479
  language: window.navigator.language,
1474
1480
  timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
1475
- event_type: eventType,
1476
- event_name: eventName,
1477
- event_data: data,
1478
- // 3. Attach Performance Data (Rust: Option<PerformanceMetrics>)
1481
+ eventType,
1482
+ eventName,
1483
+ eventData: data,
1479
1484
  performance: perfMetrics || void 0,
1480
- // 4. Attach Hardware Signals for Anomaly Detection (Rust: DeviceData)
1481
1485
  context: {
1482
1486
  device: {
1483
- hardware_concurrency: entropy.hardware_concurrency,
1484
- device_memory: entropy.device_memory,
1485
- pixel_ratio: entropy.pixel_ratio,
1486
- canvas_fingerprint: entropy.canvas_hash,
1487
+ hardwareConcurrency: entropy.hardware_concurrency,
1488
+ // Match Rust sub-struct too if needed
1489
+ deviceMemory: entropy.device_memory,
1490
+ pixelRatio: entropy.pixel_ratio,
1491
+ canvasFingerprint: entropy.canvas_hash,
1487
1492
  platform: entropy.platform
1488
1493
  },
1489
- visitor_id_local: this.visitorId
1490
- // Hint for stitching
1494
+ visitorIdLocal: this.visitorId
1491
1495
  },
1492
- client_timestamp: (/* @__PURE__ */ new Date()).toISOString()
1496
+ clientTimestamp: (/* @__PURE__ */ new Date()).toISOString()
1493
1497
  };
1494
1498
  await eventStorage.enqueue(payload);
1495
1499
  const count = await eventStorage.count();
@@ -1707,9 +1711,9 @@ var AnalyticsEngine = class {
1707
1711
  const config = this.tracker["config"];
1708
1712
  const endpoint = `${config.analyticsUrl}/api/${type}`;
1709
1713
  const payload = {
1710
- project_id: this.tracker["config"].projectId,
1711
- session_id: this.tracker.getSession(),
1712
- visitor_id: this.tracker.visitorId,
1714
+ projectId: config.projectId,
1715
+ sessionId: this.tracker.getSession(),
1716
+ visitorId: this.tracker.visitorId,
1713
1717
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1714
1718
  ...data
1715
1719
  };
@@ -1861,7 +1865,13 @@ import React2, { createContext as createContext2, useEffect as useEffect2, useRe
1861
1865
  import { usePathname, useSearchParams } from "next/navigation";
1862
1866
 
1863
1867
  // src/auth/context.tsx
1864
- import { createContext, useContext, useEffect, useState, useCallback } from "react";
1868
+ import {
1869
+ createContext,
1870
+ useContext,
1871
+ useEffect,
1872
+ useState,
1873
+ useCallback
1874
+ } from "react";
1865
1875
  import { jsx } from "react/jsx-runtime";
1866
1876
  var AuthContext = createContext(null);
1867
1877
  var AuthProvider = ({
@@ -1957,7 +1967,10 @@ var AuthProvider = ({
1957
1967
  const logout = async () => {
1958
1968
  setIsLoading(true);
1959
1969
  try {
1960
- await fetch(`${AUTH_BASE}/logout`, { method: "POST", headers: getHeaders(config) });
1970
+ await fetch(`${AUTH_BASE}/logout`, {
1971
+ method: "POST",
1972
+ headers: getHeaders(config)
1973
+ });
1961
1974
  } catch (e) {
1962
1975
  console.warn("Logout network error", e);
1963
1976
  } finally {
@@ -1994,17 +2007,23 @@ var AuthProvider = ({
1994
2007
  });
1995
2008
  if (!res.ok) throw await parseError(res);
1996
2009
  };
1997
- return /* @__PURE__ */ jsx(AuthContext.Provider, { value: {
1998
- user,
1999
- isLoading,
2000
- error,
2001
- isAuthenticated: !!user,
2002
- login,
2003
- register,
2004
- logout,
2005
- updateProfile,
2006
- requestPasswordReset
2007
- }, children });
2010
+ return /* @__PURE__ */ jsx(
2011
+ AuthContext.Provider,
2012
+ {
2013
+ value: {
2014
+ user,
2015
+ isLoading,
2016
+ error,
2017
+ isAuthenticated: !!user,
2018
+ login,
2019
+ register,
2020
+ logout,
2021
+ updateProfile,
2022
+ requestPasswordReset
2023
+ },
2024
+ children
2025
+ }
2026
+ );
2008
2027
  };
2009
2028
  var useNexusAuth = () => {
2010
2029
  const context = useContext(AuthContext);
@@ -2016,8 +2035,10 @@ var useNexusAuth = () => {
2016
2035
  function getHeaders(config) {
2017
2036
  return {
2018
2037
  "Content-Type": "application/json",
2019
- "x-nexus-project": config.projectId
2020
- // Note: We do NOT send the Master API Key here.
2038
+ "x-nexus-project": config.projectId,
2039
+ Authorization: `Bearer ${config.apiKey}`
2040
+ // 👈 CRITICAL: Send the nx_pk_ key
2041
+ // Note: We do NOT send the Master API Key here.
2021
2042
  // This is client-side. The backend uses Cookies or public tokens.
2022
2043
  };
2023
2044
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nexushub/client",
3
3
  "private": false,
4
- "version": "0.1.2",
4
+ "version": "0.1.3",
5
5
  "description": "The God-Tier NexusHub SDK",
6
6
  "type": "module",
7
7
  "main": "./dist/index.cjs",