@sendoracloud/sdk-react-native 0.18.8 → 0.19.0

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
@@ -1830,7 +1830,7 @@ var SendoraSDK = class {
1830
1830
  throw new Error("[sendoracloud] push token metadata exceeds 4KB.");
1831
1831
  }
1832
1832
  }
1833
- const data = await post(
1833
+ const res = await post(
1834
1834
  { apiUrl: this.config.apiUrl, publicKey: this.config.publicKey, debug: this.debug },
1835
1835
  "/api/v1/push/tokens",
1836
1836
  {
@@ -1843,6 +1843,11 @@ var SendoraSDK = class {
1843
1843
  metadata: reg.metadata ?? {}
1844
1844
  }
1845
1845
  );
1846
+ if (!res || !res.ok) {
1847
+ throw new Error(`[sendoracloud] push token registration failed (HTTP ${res?.status ?? "network"}).`);
1848
+ }
1849
+ const parsed = await res.json();
1850
+ const data = parsed?.data;
1846
1851
  if (!data?.tokenId) {
1847
1852
  throw new Error("[sendoracloud] push token registered but server returned no tokenId \u2014 upgrade backend to >= s58.16.");
1848
1853
  }
@@ -1853,6 +1858,14 @@ var SendoraSDK = class {
1853
1858
  * `sendora.push.registerToken(...)` works consistently across all 5 SDKs.
1854
1859
  * Backed by the same registerPushToken() implementation; kept top-level
1855
1860
  * too for backwards compatibility with the s47 release.
1861
+ *
1862
+ * Tier 3 (s58.70): added `liveActivities.startToken()` and
1863
+ * `geofences.{list,recordEvent}()`. These are JS-side shims around
1864
+ * the backend wire calls — the native bridge work (ActivityKit on
1865
+ * iOS, CoreLocation geofencing, Android NotificationCompat + Geo
1866
+ * APIs) still lives in your app code. Once your native side has
1867
+ * the activity push token / geofence trigger in hand, hand it to
1868
+ * the SDK and we'll persist + dispatch server-side.
1856
1869
  */
1857
1870
  get push() {
1858
1871
  const self = this;
@@ -1867,6 +1880,88 @@ var SendoraSDK = class {
1867
1880
  "/push/track-open",
1868
1881
  body
1869
1882
  );
1883
+ },
1884
+ liveActivities: {
1885
+ /**
1886
+ * Report a freshly-started iOS Live Activity (or Android Live
1887
+ * Update on Android 14+) push token to Sendora so server-side
1888
+ * `PATCH /push/live-activities/:id/update` calls can dispatch
1889
+ * via APNs (iOS) or FCM data-only (Android).
1890
+ *
1891
+ * Host app calls this once per Activity lifecycle, right
1892
+ * after `Activity.pushTokenUpdates` (iOS) or your Android
1893
+ * NotificationCompat setup hands you the push token.
1894
+ */
1895
+ startToken: async (input) => {
1896
+ if (!self.config) throw new Error("[sendoracloud] init() must complete before push.liveActivities.startToken().");
1897
+ const res = await post(
1898
+ { apiUrl: self.config.apiUrl, publicKey: self.config.publicKey, debug: self.debug },
1899
+ "/push/live-activities/start-token",
1900
+ {
1901
+ pushToken: input.pushToken,
1902
+ activityType: input.activityType,
1903
+ platform: input.platform ?? "ios",
1904
+ externalId: input.externalId,
1905
+ userId: input.userId,
1906
+ attributes: input.attributes ?? {},
1907
+ contentState: input.contentState ?? {},
1908
+ bundleId: input.bundleId
1909
+ }
1910
+ );
1911
+ if (!res || !res.ok) {
1912
+ throw new Error(`[sendoracloud] live-activity start-token failed (HTTP ${res?.status ?? "network"}).`);
1913
+ }
1914
+ const parsed = await res.json();
1915
+ const data = parsed?.data;
1916
+ if (!data?.id) throw new Error("[sendoracloud] live-activity start-token: server returned no id.");
1917
+ return { id: data.id, status: data.status ?? "active" };
1918
+ }
1919
+ },
1920
+ geofences: {
1921
+ /**
1922
+ * Fetch the enabled geofences for this device. The SDK doesn't
1923
+ * register them with the OS — that's app-side native work
1924
+ * (CLLocationManager.startMonitoring on iOS, GeofencingClient
1925
+ * on Android). Sort order is server-controlled by priority
1926
+ * asc so the caller can clamp to the OS cap (iOS 20, Android
1927
+ * 100) by truncating the list.
1928
+ */
1929
+ list: async () => {
1930
+ if (!self.config) throw new Error("[sendoracloud] init() must complete before push.geofences.list().");
1931
+ const res = await getJson(
1932
+ { apiUrl: self.config.apiUrl, publicKey: self.config.publicKey, debug: self.debug },
1933
+ "/push/geofences/list-for-device"
1934
+ );
1935
+ if (!res || !res.ok) {
1936
+ throw new Error(`[sendoracloud] geofences list failed (HTTP ${res?.status ?? "network"}).`);
1937
+ }
1938
+ const parsed = await res.json();
1939
+ return parsed?.data ?? [];
1940
+ },
1941
+ /**
1942
+ * Report a geofence enter / exit / dwell event. Backend writes
1943
+ * a `geofence.<kind>` event row + fires any workflows triggered
1944
+ * on that geofence id. Call from the native handler that
1945
+ * receives the OS region notification.
1946
+ */
1947
+ recordEvent: async (input) => {
1948
+ if (!self.config) throw new Error("[sendoracloud] init() must complete before push.geofences.recordEvent().");
1949
+ const res = await post(
1950
+ { apiUrl: self.config.apiUrl, publicKey: self.config.publicKey, debug: self.debug },
1951
+ "/push/geofences/event",
1952
+ {
1953
+ geofenceId: input.geofenceId,
1954
+ kind: input.kind,
1955
+ lat: input.lat,
1956
+ lng: input.lng,
1957
+ accuracyMeters: input.accuracyMeters,
1958
+ dwellSeconds: input.dwellSeconds
1959
+ }
1960
+ );
1961
+ if (!res || !res.ok) {
1962
+ throw new Error(`[sendoracloud] geofence event failed (HTTP ${res?.status ?? "network"}).`);
1963
+ }
1964
+ }
1870
1965
  }
1871
1966
  };
1872
1967
  }
package/dist/index.d.cts CHANGED
@@ -759,10 +759,54 @@ declare class SendoraSDK {
759
759
  * `sendora.push.registerToken(...)` works consistently across all 5 SDKs.
760
760
  * Backed by the same registerPushToken() implementation; kept top-level
761
761
  * too for backwards compatibility with the s47 release.
762
+ *
763
+ * Tier 3 (s58.70): added `liveActivities.startToken()` and
764
+ * `geofences.{list,recordEvent}()`. These are JS-side shims around
765
+ * the backend wire calls — the native bridge work (ActivityKit on
766
+ * iOS, CoreLocation geofencing, Android NotificationCompat + Geo
767
+ * APIs) still lives in your app code. Once your native side has
768
+ * the activity push token / geofence trigger in hand, hand it to
769
+ * the SDK and we'll persist + dispatch server-side.
762
770
  */
763
771
  get push(): {
764
772
  registerToken: (reg: PushTokenRegistration) => Promise<PushTokenReceipt>;
765
773
  trackOpen: (sendId: string, clickAction?: string) => Promise<void>;
774
+ liveActivities: {
775
+ startToken: (input: {
776
+ pushToken: string;
777
+ activityType: string;
778
+ platform?: "ios" | "android";
779
+ externalId?: string;
780
+ userId?: string;
781
+ attributes?: Record<string, unknown>;
782
+ contentState?: Record<string, unknown>;
783
+ bundleId?: string;
784
+ }) => Promise<{
785
+ id: string;
786
+ status: string;
787
+ }>;
788
+ };
789
+ geofences: {
790
+ list: () => Promise<Array<{
791
+ id: string;
792
+ name: string;
793
+ lat: number;
794
+ lng: number;
795
+ radiusMeters: number;
796
+ priority: number;
797
+ enabled: boolean;
798
+ triggerOn: string[];
799
+ properties?: Record<string, unknown>;
800
+ }>>;
801
+ recordEvent: (input: {
802
+ geofenceId: string;
803
+ kind: "enter" | "exit" | "dwell";
804
+ lat?: number;
805
+ lng?: number;
806
+ accuracyMeters?: number;
807
+ dwellSeconds?: number;
808
+ }) => Promise<void>;
809
+ };
766
810
  };
767
811
  /**
768
812
  * Attribution namespace — mobile install + deferred deep-link reporting.
package/dist/index.d.ts CHANGED
@@ -759,10 +759,54 @@ declare class SendoraSDK {
759
759
  * `sendora.push.registerToken(...)` works consistently across all 5 SDKs.
760
760
  * Backed by the same registerPushToken() implementation; kept top-level
761
761
  * too for backwards compatibility with the s47 release.
762
+ *
763
+ * Tier 3 (s58.70): added `liveActivities.startToken()` and
764
+ * `geofences.{list,recordEvent}()`. These are JS-side shims around
765
+ * the backend wire calls — the native bridge work (ActivityKit on
766
+ * iOS, CoreLocation geofencing, Android NotificationCompat + Geo
767
+ * APIs) still lives in your app code. Once your native side has
768
+ * the activity push token / geofence trigger in hand, hand it to
769
+ * the SDK and we'll persist + dispatch server-side.
762
770
  */
763
771
  get push(): {
764
772
  registerToken: (reg: PushTokenRegistration) => Promise<PushTokenReceipt>;
765
773
  trackOpen: (sendId: string, clickAction?: string) => Promise<void>;
774
+ liveActivities: {
775
+ startToken: (input: {
776
+ pushToken: string;
777
+ activityType: string;
778
+ platform?: "ios" | "android";
779
+ externalId?: string;
780
+ userId?: string;
781
+ attributes?: Record<string, unknown>;
782
+ contentState?: Record<string, unknown>;
783
+ bundleId?: string;
784
+ }) => Promise<{
785
+ id: string;
786
+ status: string;
787
+ }>;
788
+ };
789
+ geofences: {
790
+ list: () => Promise<Array<{
791
+ id: string;
792
+ name: string;
793
+ lat: number;
794
+ lng: number;
795
+ radiusMeters: number;
796
+ priority: number;
797
+ enabled: boolean;
798
+ triggerOn: string[];
799
+ properties?: Record<string, unknown>;
800
+ }>>;
801
+ recordEvent: (input: {
802
+ geofenceId: string;
803
+ kind: "enter" | "exit" | "dwell";
804
+ lat?: number;
805
+ lng?: number;
806
+ accuracyMeters?: number;
807
+ dwellSeconds?: number;
808
+ }) => Promise<void>;
809
+ };
766
810
  };
767
811
  /**
768
812
  * Attribution namespace — mobile install + deferred deep-link reporting.
package/dist/index.js CHANGED
@@ -1792,7 +1792,7 @@ var SendoraSDK = class {
1792
1792
  throw new Error("[sendoracloud] push token metadata exceeds 4KB.");
1793
1793
  }
1794
1794
  }
1795
- const data = await post(
1795
+ const res = await post(
1796
1796
  { apiUrl: this.config.apiUrl, publicKey: this.config.publicKey, debug: this.debug },
1797
1797
  "/api/v1/push/tokens",
1798
1798
  {
@@ -1805,6 +1805,11 @@ var SendoraSDK = class {
1805
1805
  metadata: reg.metadata ?? {}
1806
1806
  }
1807
1807
  );
1808
+ if (!res || !res.ok) {
1809
+ throw new Error(`[sendoracloud] push token registration failed (HTTP ${res?.status ?? "network"}).`);
1810
+ }
1811
+ const parsed = await res.json();
1812
+ const data = parsed?.data;
1808
1813
  if (!data?.tokenId) {
1809
1814
  throw new Error("[sendoracloud] push token registered but server returned no tokenId \u2014 upgrade backend to >= s58.16.");
1810
1815
  }
@@ -1815,6 +1820,14 @@ var SendoraSDK = class {
1815
1820
  * `sendora.push.registerToken(...)` works consistently across all 5 SDKs.
1816
1821
  * Backed by the same registerPushToken() implementation; kept top-level
1817
1822
  * too for backwards compatibility with the s47 release.
1823
+ *
1824
+ * Tier 3 (s58.70): added `liveActivities.startToken()` and
1825
+ * `geofences.{list,recordEvent}()`. These are JS-side shims around
1826
+ * the backend wire calls — the native bridge work (ActivityKit on
1827
+ * iOS, CoreLocation geofencing, Android NotificationCompat + Geo
1828
+ * APIs) still lives in your app code. Once your native side has
1829
+ * the activity push token / geofence trigger in hand, hand it to
1830
+ * the SDK and we'll persist + dispatch server-side.
1818
1831
  */
1819
1832
  get push() {
1820
1833
  const self = this;
@@ -1829,6 +1842,88 @@ var SendoraSDK = class {
1829
1842
  "/push/track-open",
1830
1843
  body
1831
1844
  );
1845
+ },
1846
+ liveActivities: {
1847
+ /**
1848
+ * Report a freshly-started iOS Live Activity (or Android Live
1849
+ * Update on Android 14+) push token to Sendora so server-side
1850
+ * `PATCH /push/live-activities/:id/update` calls can dispatch
1851
+ * via APNs (iOS) or FCM data-only (Android).
1852
+ *
1853
+ * Host app calls this once per Activity lifecycle, right
1854
+ * after `Activity.pushTokenUpdates` (iOS) or your Android
1855
+ * NotificationCompat setup hands you the push token.
1856
+ */
1857
+ startToken: async (input) => {
1858
+ if (!self.config) throw new Error("[sendoracloud] init() must complete before push.liveActivities.startToken().");
1859
+ const res = await post(
1860
+ { apiUrl: self.config.apiUrl, publicKey: self.config.publicKey, debug: self.debug },
1861
+ "/push/live-activities/start-token",
1862
+ {
1863
+ pushToken: input.pushToken,
1864
+ activityType: input.activityType,
1865
+ platform: input.platform ?? "ios",
1866
+ externalId: input.externalId,
1867
+ userId: input.userId,
1868
+ attributes: input.attributes ?? {},
1869
+ contentState: input.contentState ?? {},
1870
+ bundleId: input.bundleId
1871
+ }
1872
+ );
1873
+ if (!res || !res.ok) {
1874
+ throw new Error(`[sendoracloud] live-activity start-token failed (HTTP ${res?.status ?? "network"}).`);
1875
+ }
1876
+ const parsed = await res.json();
1877
+ const data = parsed?.data;
1878
+ if (!data?.id) throw new Error("[sendoracloud] live-activity start-token: server returned no id.");
1879
+ return { id: data.id, status: data.status ?? "active" };
1880
+ }
1881
+ },
1882
+ geofences: {
1883
+ /**
1884
+ * Fetch the enabled geofences for this device. The SDK doesn't
1885
+ * register them with the OS — that's app-side native work
1886
+ * (CLLocationManager.startMonitoring on iOS, GeofencingClient
1887
+ * on Android). Sort order is server-controlled by priority
1888
+ * asc so the caller can clamp to the OS cap (iOS 20, Android
1889
+ * 100) by truncating the list.
1890
+ */
1891
+ list: async () => {
1892
+ if (!self.config) throw new Error("[sendoracloud] init() must complete before push.geofences.list().");
1893
+ const res = await getJson(
1894
+ { apiUrl: self.config.apiUrl, publicKey: self.config.publicKey, debug: self.debug },
1895
+ "/push/geofences/list-for-device"
1896
+ );
1897
+ if (!res || !res.ok) {
1898
+ throw new Error(`[sendoracloud] geofences list failed (HTTP ${res?.status ?? "network"}).`);
1899
+ }
1900
+ const parsed = await res.json();
1901
+ return parsed?.data ?? [];
1902
+ },
1903
+ /**
1904
+ * Report a geofence enter / exit / dwell event. Backend writes
1905
+ * a `geofence.<kind>` event row + fires any workflows triggered
1906
+ * on that geofence id. Call from the native handler that
1907
+ * receives the OS region notification.
1908
+ */
1909
+ recordEvent: async (input) => {
1910
+ if (!self.config) throw new Error("[sendoracloud] init() must complete before push.geofences.recordEvent().");
1911
+ const res = await post(
1912
+ { apiUrl: self.config.apiUrl, publicKey: self.config.publicKey, debug: self.debug },
1913
+ "/push/geofences/event",
1914
+ {
1915
+ geofenceId: input.geofenceId,
1916
+ kind: input.kind,
1917
+ lat: input.lat,
1918
+ lng: input.lng,
1919
+ accuracyMeters: input.accuracyMeters,
1920
+ dwellSeconds: input.dwellSeconds
1921
+ }
1922
+ );
1923
+ if (!res || !res.ok) {
1924
+ throw new Error(`[sendoracloud] geofence event failed (HTTP ${res?.status ?? "network"}).`);
1925
+ }
1926
+ }
1832
1927
  }
1833
1928
  };
1834
1929
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendoracloud/sdk-react-native",
3
- "version": "0.18.8",
3
+ "version": "0.19.0",
4
4
  "description": "Sendora Cloud React Native + Expo SDK — analytics, identity, push-token registration, auth, deep links (Branch / Firebase Dynamic Links parity). Auth + analytics + deep links work in Expo Go; push token registration requires a Dev Client (EAS Build or `npx expo prebuild`).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",