krisspy-sdk 0.9.1 → 0.9.2

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.d.mts CHANGED
@@ -758,28 +758,37 @@ declare class KrisspyRealtime {
758
758
  *
759
759
  * Tracks page views, sessions, custom events. Sends batched events
760
760
  * to the analytics ingest endpoint. Works with SPAs (intercepts pushState).
761
- * Browser-only module - safely no-ops in React Native / Node.js.
761
+ * Works on Web (browser), React Native / Expo, and Node.js.
762
762
  *
763
763
  * Supports two backends:
764
764
  * - Krisspy internal analytics (default, via /api/v1/analytics/events)
765
- * - OpenPanel (when openpanelClientId is provided, uses @openpanel/web SDK)
765
+ * - OpenPanel (when openpanelClientId is provided)
766
+ * - Web: uses @openpanel/web SDK
767
+ * - React Native / Expo: uses @openpanel/react-native SDK
766
768
  *
767
769
  * @example
768
770
  * const krisspy = createClient({ backendId: '...', apiKey: '...' })
769
771
  * krisspy.analytics.init({ autoTrackPageViews: true })
770
772
  * krisspy.analytics.track('button_click', { label: 'signup' })
771
773
  *
772
- * // With OpenPanel:
774
+ * // With OpenPanel (web):
773
775
  * krisspy.analytics.init({
774
776
  * openpanelClientId: '049c50ff-...',
775
777
  * openpanelApiUrl: 'https://api-openpanel.krisspy.ai',
776
778
  * })
779
+ *
780
+ * // With OpenPanel (React Native / Expo):
781
+ * krisspy.analytics.init({
782
+ * openpanelClientId: '049c50ff-...',
783
+ * openpanelApiUrl: 'https://api-openpanel.krisspy.ai',
784
+ * storage: AsyncStorage, // optional — persists session across app restarts
785
+ * })
777
786
  */
778
787
 
779
788
  interface AnalyticsInitOptions {
780
789
  /** Auto-track page views on init + navigation (default: true) */
781
790
  autoTrackPageViews?: boolean;
782
- /** Auto-track SPA navigation via pushState/popstate (default: true) */
791
+ /** Auto-track SPA navigation via pushState/popstate (default: true, web only) */
783
792
  autoTrackNavigation?: boolean;
784
793
  /** Flush interval in ms (default: 5000) */
785
794
  flushInterval?: number;
@@ -789,11 +798,11 @@ interface AnalyticsInitOptions {
789
798
  openpanelClientId?: string;
790
799
  /** OpenPanel API URL for self-hosted instances (default: https://api-openpanel.krisspy.ai) */
791
800
  openpanelApiUrl?: string;
792
- /** Track outgoing links (OpenPanel, default: true) */
801
+ /** Track outgoing links (OpenPanel web, default: true) */
793
802
  trackOutgoingLinks?: boolean;
794
- /** Track elements with data-track attributes (OpenPanel, default: true) */
803
+ /** Track elements with data-track attributes (OpenPanel web, default: true) */
795
804
  trackAttributes?: boolean;
796
- /** Track hash changes in URL (OpenPanel, default: false) */
805
+ /** Track hash changes in URL (OpenPanel web, default: false) */
797
806
  trackHashChanges?: boolean;
798
807
  /** Disable tracking entirely (OpenPanel, default: false) */
799
808
  disabled?: boolean;
@@ -802,6 +811,16 @@ interface AnalyticsInitOptions {
802
811
  name: string;
803
812
  properties?: Record<string, any>;
804
813
  }) => boolean;
814
+ /**
815
+ * Custom storage adapter for session ID persistence on React Native.
816
+ * Pass AsyncStorage or MMKV here so the session survives app restarts.
817
+ * On web, localStorage is used automatically.
818
+ *
819
+ * @example
820
+ * import AsyncStorage from '@react-native-async-storage/async-storage'
821
+ * krisspy.analytics.init({ openpanelClientId: '...', storage: AsyncStorage })
822
+ */
823
+ storage?: StorageAdapter;
805
824
  }
806
825
  interface AnalyticsEvent {
807
826
  eventName: string;
@@ -828,8 +847,9 @@ declare class KrisspyAnalytics {
828
847
  private useOpenPanel;
829
848
  constructor(http: HttpClient, backendId: string);
830
849
  /**
831
- * Initialize analytics tracking
832
- * No-ops in non-browser environments (React Native, Node.js)
850
+ * Initialize analytics tracking.
851
+ * Works on web (browser), React Native / Expo, and Node.js.
852
+ * In Node.js without openpanelClientId, auto-tracking is skipped (manual track() still works).
833
853
  */
834
854
  init(options?: AnalyticsInitOptions): void;
835
855
  /**
@@ -902,10 +922,14 @@ declare class KrisspyAnalytics {
902
922
  private setupNavigationTracking;
903
923
  /**
904
924
  * Initialize OpenPanel SDK dynamically.
905
- * Loads @openpanel/web at runtime (must be installed by the user).
906
- * Falls back gracefully if not available.
925
+ * - React Native / Expo: loads @openpanel/react-native
926
+ * - Browser: loads @openpanel/web
927
+ * Falls back gracefully to internal analytics if package not installed.
907
928
  */
908
929
  private initOpenPanel;
930
+ private initOpenPanelReactNative;
931
+ private initOpenPanelWeb;
932
+ private fallbackToInternal;
909
933
  }
910
934
 
911
935
  /**
package/dist/index.d.ts CHANGED
@@ -758,28 +758,37 @@ declare class KrisspyRealtime {
758
758
  *
759
759
  * Tracks page views, sessions, custom events. Sends batched events
760
760
  * to the analytics ingest endpoint. Works with SPAs (intercepts pushState).
761
- * Browser-only module - safely no-ops in React Native / Node.js.
761
+ * Works on Web (browser), React Native / Expo, and Node.js.
762
762
  *
763
763
  * Supports two backends:
764
764
  * - Krisspy internal analytics (default, via /api/v1/analytics/events)
765
- * - OpenPanel (when openpanelClientId is provided, uses @openpanel/web SDK)
765
+ * - OpenPanel (when openpanelClientId is provided)
766
+ * - Web: uses @openpanel/web SDK
767
+ * - React Native / Expo: uses @openpanel/react-native SDK
766
768
  *
767
769
  * @example
768
770
  * const krisspy = createClient({ backendId: '...', apiKey: '...' })
769
771
  * krisspy.analytics.init({ autoTrackPageViews: true })
770
772
  * krisspy.analytics.track('button_click', { label: 'signup' })
771
773
  *
772
- * // With OpenPanel:
774
+ * // With OpenPanel (web):
773
775
  * krisspy.analytics.init({
774
776
  * openpanelClientId: '049c50ff-...',
775
777
  * openpanelApiUrl: 'https://api-openpanel.krisspy.ai',
776
778
  * })
779
+ *
780
+ * // With OpenPanel (React Native / Expo):
781
+ * krisspy.analytics.init({
782
+ * openpanelClientId: '049c50ff-...',
783
+ * openpanelApiUrl: 'https://api-openpanel.krisspy.ai',
784
+ * storage: AsyncStorage, // optional — persists session across app restarts
785
+ * })
777
786
  */
778
787
 
779
788
  interface AnalyticsInitOptions {
780
789
  /** Auto-track page views on init + navigation (default: true) */
781
790
  autoTrackPageViews?: boolean;
782
- /** Auto-track SPA navigation via pushState/popstate (default: true) */
791
+ /** Auto-track SPA navigation via pushState/popstate (default: true, web only) */
783
792
  autoTrackNavigation?: boolean;
784
793
  /** Flush interval in ms (default: 5000) */
785
794
  flushInterval?: number;
@@ -789,11 +798,11 @@ interface AnalyticsInitOptions {
789
798
  openpanelClientId?: string;
790
799
  /** OpenPanel API URL for self-hosted instances (default: https://api-openpanel.krisspy.ai) */
791
800
  openpanelApiUrl?: string;
792
- /** Track outgoing links (OpenPanel, default: true) */
801
+ /** Track outgoing links (OpenPanel web, default: true) */
793
802
  trackOutgoingLinks?: boolean;
794
- /** Track elements with data-track attributes (OpenPanel, default: true) */
803
+ /** Track elements with data-track attributes (OpenPanel web, default: true) */
795
804
  trackAttributes?: boolean;
796
- /** Track hash changes in URL (OpenPanel, default: false) */
805
+ /** Track hash changes in URL (OpenPanel web, default: false) */
797
806
  trackHashChanges?: boolean;
798
807
  /** Disable tracking entirely (OpenPanel, default: false) */
799
808
  disabled?: boolean;
@@ -802,6 +811,16 @@ interface AnalyticsInitOptions {
802
811
  name: string;
803
812
  properties?: Record<string, any>;
804
813
  }) => boolean;
814
+ /**
815
+ * Custom storage adapter for session ID persistence on React Native.
816
+ * Pass AsyncStorage or MMKV here so the session survives app restarts.
817
+ * On web, localStorage is used automatically.
818
+ *
819
+ * @example
820
+ * import AsyncStorage from '@react-native-async-storage/async-storage'
821
+ * krisspy.analytics.init({ openpanelClientId: '...', storage: AsyncStorage })
822
+ */
823
+ storage?: StorageAdapter;
805
824
  }
806
825
  interface AnalyticsEvent {
807
826
  eventName: string;
@@ -828,8 +847,9 @@ declare class KrisspyAnalytics {
828
847
  private useOpenPanel;
829
848
  constructor(http: HttpClient, backendId: string);
830
849
  /**
831
- * Initialize analytics tracking
832
- * No-ops in non-browser environments (React Native, Node.js)
850
+ * Initialize analytics tracking.
851
+ * Works on web (browser), React Native / Expo, and Node.js.
852
+ * In Node.js without openpanelClientId, auto-tracking is skipped (manual track() still works).
833
853
  */
834
854
  init(options?: AnalyticsInitOptions): void;
835
855
  /**
@@ -902,10 +922,14 @@ declare class KrisspyAnalytics {
902
922
  private setupNavigationTracking;
903
923
  /**
904
924
  * Initialize OpenPanel SDK dynamically.
905
- * Loads @openpanel/web at runtime (must be installed by the user).
906
- * Falls back gracefully if not available.
925
+ * - React Native / Expo: loads @openpanel/react-native
926
+ * - Browser: loads @openpanel/web
927
+ * Falls back gracefully to internal analytics if package not installed.
907
928
  */
908
929
  private initOpenPanel;
930
+ private initOpenPanelReactNative;
931
+ private initOpenPanelWeb;
932
+ private fallbackToInternal;
909
933
  }
910
934
 
911
935
  /**
package/dist/index.js CHANGED
@@ -1324,12 +1324,12 @@ var KrisspyAnalytics = class {
1324
1324
  this.backendId = backendId;
1325
1325
  }
1326
1326
  /**
1327
- * Initialize analytics tracking
1328
- * No-ops in non-browser environments (React Native, Node.js)
1327
+ * Initialize analytics tracking.
1328
+ * Works on web (browser), React Native / Expo, and Node.js.
1329
+ * In Node.js without openpanelClientId, auto-tracking is skipped (manual track() still works).
1329
1330
  */
1330
1331
  init(options) {
1331
1332
  if (this.initialized) return;
1332
- if (!isBrowser()) return;
1333
1333
  this.options = __spreadValues({
1334
1334
  autoTrackPageViews: true,
1335
1335
  autoTrackNavigation: true,
@@ -1342,6 +1342,11 @@ var KrisspyAnalytics = class {
1342
1342
  this.initOpenPanel();
1343
1343
  return;
1344
1344
  }
1345
+ if (!isBrowser()) {
1346
+ this.sessionId = this.getOrCreateSessionId();
1347
+ this.initialized = true;
1348
+ return;
1349
+ }
1345
1350
  this.sessionId = this.getOrCreateSessionId();
1346
1351
  this.initialized = true;
1347
1352
  if (this.options.autoTrackPageViews) {
@@ -1588,12 +1593,39 @@ var KrisspyAnalytics = class {
1588
1593
  }
1589
1594
  /**
1590
1595
  * Initialize OpenPanel SDK dynamically.
1591
- * Loads @openpanel/web at runtime (must be installed by the user).
1592
- * Falls back gracefully if not available.
1596
+ * - React Native / Expo: loads @openpanel/react-native
1597
+ * - Browser: loads @openpanel/web
1598
+ * Falls back gracefully to internal analytics if package not installed.
1593
1599
  */
1594
1600
  async initOpenPanel() {
1595
1601
  const clientId = this.options.openpanelClientId;
1596
1602
  const apiUrl = this.options.openpanelApiUrl || "https://api-openpanel.krisspy.ai";
1603
+ if (isReactNative()) {
1604
+ await this.initOpenPanelReactNative(clientId, apiUrl);
1605
+ } else {
1606
+ await this.initOpenPanelWeb(clientId, apiUrl);
1607
+ }
1608
+ }
1609
+ async initOpenPanelReactNative(clientId, apiUrl) {
1610
+ try {
1611
+ const { OpenPanel } = await import("@openpanel/react-native");
1612
+ this.openpanel = new OpenPanel({
1613
+ clientId,
1614
+ apiUrl,
1615
+ disabled: this.options.disabled,
1616
+ filter: this.options.filter
1617
+ });
1618
+ if (this.options.debug) {
1619
+ console.log("[Krisspy Analytics \u2192 OpenPanel RN] Initialized", { clientId, apiUrl });
1620
+ }
1621
+ } catch (e) {
1622
+ console.warn(
1623
+ "[Krisspy Analytics] @openpanel/react-native not found. Install it with: npx expo install @openpanel/react-native\nFalling back to internal analytics."
1624
+ );
1625
+ this.fallbackToInternal();
1626
+ }
1627
+ }
1628
+ async initOpenPanelWeb(clientId, apiUrl) {
1597
1629
  try {
1598
1630
  const { OpenPanel } = await import("@openpanel/web");
1599
1631
  this.openpanel = new OpenPanel({
@@ -1609,13 +1641,18 @@ var KrisspyAnalytics = class {
1609
1641
  if (this.options.debug) {
1610
1642
  console.log("[Krisspy Analytics \u2192 OpenPanel] Initialized", { clientId, apiUrl });
1611
1643
  }
1612
- } catch (err) {
1644
+ } catch (e) {
1613
1645
  console.warn(
1614
1646
  "[Krisspy Analytics] @openpanel/web not found. Install it with: npm install @openpanel/web\nFalling back to internal analytics."
1615
1647
  );
1616
- this.useOpenPanel = false;
1617
- this.openpanel = null;
1618
- this.sessionId = this.getOrCreateSessionId();
1648
+ this.fallbackToInternal();
1649
+ }
1650
+ }
1651
+ fallbackToInternal() {
1652
+ this.useOpenPanel = false;
1653
+ this.openpanel = null;
1654
+ this.sessionId = this.getOrCreateSessionId();
1655
+ if (isBrowser()) {
1619
1656
  if (this.options.autoTrackPageViews) {
1620
1657
  this.track("session_start", {});
1621
1658
  this.track("page_view", { url: window.location.href, referrer: document.referrer });
@@ -1623,8 +1660,8 @@ var KrisspyAnalytics = class {
1623
1660
  if (this.options.autoTrackNavigation) {
1624
1661
  this.setupNavigationTracking();
1625
1662
  }
1626
- this.flushTimer = setInterval(() => this.flush(), this.options.flushInterval);
1627
1663
  }
1664
+ this.flushTimer = setInterval(() => this.flush(), this.options.flushInterval);
1628
1665
  }
1629
1666
  };
1630
1667
 
package/dist/index.mjs CHANGED
@@ -1279,12 +1279,12 @@ var KrisspyAnalytics = class {
1279
1279
  this.backendId = backendId;
1280
1280
  }
1281
1281
  /**
1282
- * Initialize analytics tracking
1283
- * No-ops in non-browser environments (React Native, Node.js)
1282
+ * Initialize analytics tracking.
1283
+ * Works on web (browser), React Native / Expo, and Node.js.
1284
+ * In Node.js without openpanelClientId, auto-tracking is skipped (manual track() still works).
1284
1285
  */
1285
1286
  init(options) {
1286
1287
  if (this.initialized) return;
1287
- if (!isBrowser()) return;
1288
1288
  this.options = __spreadValues({
1289
1289
  autoTrackPageViews: true,
1290
1290
  autoTrackNavigation: true,
@@ -1297,6 +1297,11 @@ var KrisspyAnalytics = class {
1297
1297
  this.initOpenPanel();
1298
1298
  return;
1299
1299
  }
1300
+ if (!isBrowser()) {
1301
+ this.sessionId = this.getOrCreateSessionId();
1302
+ this.initialized = true;
1303
+ return;
1304
+ }
1300
1305
  this.sessionId = this.getOrCreateSessionId();
1301
1306
  this.initialized = true;
1302
1307
  if (this.options.autoTrackPageViews) {
@@ -1543,12 +1548,39 @@ var KrisspyAnalytics = class {
1543
1548
  }
1544
1549
  /**
1545
1550
  * Initialize OpenPanel SDK dynamically.
1546
- * Loads @openpanel/web at runtime (must be installed by the user).
1547
- * Falls back gracefully if not available.
1551
+ * - React Native / Expo: loads @openpanel/react-native
1552
+ * - Browser: loads @openpanel/web
1553
+ * Falls back gracefully to internal analytics if package not installed.
1548
1554
  */
1549
1555
  async initOpenPanel() {
1550
1556
  const clientId = this.options.openpanelClientId;
1551
1557
  const apiUrl = this.options.openpanelApiUrl || "https://api-openpanel.krisspy.ai";
1558
+ if (isReactNative()) {
1559
+ await this.initOpenPanelReactNative(clientId, apiUrl);
1560
+ } else {
1561
+ await this.initOpenPanelWeb(clientId, apiUrl);
1562
+ }
1563
+ }
1564
+ async initOpenPanelReactNative(clientId, apiUrl) {
1565
+ try {
1566
+ const { OpenPanel } = await import("@openpanel/react-native");
1567
+ this.openpanel = new OpenPanel({
1568
+ clientId,
1569
+ apiUrl,
1570
+ disabled: this.options.disabled,
1571
+ filter: this.options.filter
1572
+ });
1573
+ if (this.options.debug) {
1574
+ console.log("[Krisspy Analytics \u2192 OpenPanel RN] Initialized", { clientId, apiUrl });
1575
+ }
1576
+ } catch (e) {
1577
+ console.warn(
1578
+ "[Krisspy Analytics] @openpanel/react-native not found. Install it with: npx expo install @openpanel/react-native\nFalling back to internal analytics."
1579
+ );
1580
+ this.fallbackToInternal();
1581
+ }
1582
+ }
1583
+ async initOpenPanelWeb(clientId, apiUrl) {
1552
1584
  try {
1553
1585
  const { OpenPanel } = await import("@openpanel/web");
1554
1586
  this.openpanel = new OpenPanel({
@@ -1564,13 +1596,18 @@ var KrisspyAnalytics = class {
1564
1596
  if (this.options.debug) {
1565
1597
  console.log("[Krisspy Analytics \u2192 OpenPanel] Initialized", { clientId, apiUrl });
1566
1598
  }
1567
- } catch (err) {
1599
+ } catch (e) {
1568
1600
  console.warn(
1569
1601
  "[Krisspy Analytics] @openpanel/web not found. Install it with: npm install @openpanel/web\nFalling back to internal analytics."
1570
1602
  );
1571
- this.useOpenPanel = false;
1572
- this.openpanel = null;
1573
- this.sessionId = this.getOrCreateSessionId();
1603
+ this.fallbackToInternal();
1604
+ }
1605
+ }
1606
+ fallbackToInternal() {
1607
+ this.useOpenPanel = false;
1608
+ this.openpanel = null;
1609
+ this.sessionId = this.getOrCreateSessionId();
1610
+ if (isBrowser()) {
1574
1611
  if (this.options.autoTrackPageViews) {
1575
1612
  this.track("session_start", {});
1576
1613
  this.track("page_view", { url: window.location.href, referrer: document.referrer });
@@ -1578,8 +1615,8 @@ var KrisspyAnalytics = class {
1578
1615
  if (this.options.autoTrackNavigation) {
1579
1616
  this.setupNavigationTracking();
1580
1617
  }
1581
- this.flushTimer = setInterval(() => this.flush(), this.options.flushInterval);
1582
1618
  }
1619
+ this.flushTimer = setInterval(() => this.flush(), this.options.flushInterval);
1583
1620
  }
1584
1621
  };
1585
1622
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "krisspy-sdk",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "Krisspy Cloud SDK - Database, Auth, Storage, and Functions for your apps",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -44,6 +44,14 @@
44
44
  "dependencies": {
45
45
  "@openpanel/web": "^1.0.0"
46
46
  },
47
+ "peerDependencies": {
48
+ "@openpanel/react-native": "^1.0.0"
49
+ },
50
+ "peerDependenciesMeta": {
51
+ "@openpanel/react-native": {
52
+ "optional": true
53
+ }
54
+ },
47
55
  "devDependencies": {
48
56
  "@types/node": "^20.0.0",
49
57
  "tsup": "^8.0.0",