@mushi-mushi/react-native 0.20.1 → 0.22.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.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, FC, ReactElement } from 'react';
3
- import { MushiRewardsConfig, MushiPageContext, MushiBreadcrumb, MushiReporterReport, MushiReporterComment, MushiHallOfFameEntry, MushiTierResult, MushiReputationResult, MushiAssistantReply } from '@mushi-mushi/core';
3
+ import { MushiAnalyticsConfig, MushiRewardsConfig, MushiPageContext, MushiBreadcrumb, MushiReporterReport, MushiReporterComment, MushiHallOfFameEntry, MushiPropertyValue, MushiTierResult, MushiReputationResult, MushiAssistantReply } from '@mushi-mushi/core';
4
4
  export { MushiHallOfFameEntry, MushiReporterComment, MushiReporterReport } from '@mushi-mushi/core';
5
5
 
6
6
  interface ConsoleEntry {
@@ -42,6 +42,38 @@ interface DeviceInfo {
42
42
  }
43
43
  declare function getDeviceInfo(): DeviceInfo;
44
44
 
45
+ /**
46
+ * FILE: packages/react-native/src/analytics/event-tracker.ts
47
+ * PURPOSE: Product-analytics batcher behind `useMushi().track()` on React Native.
48
+ *
49
+ * OVERVIEW:
50
+ * - The core tracker (`@mushi-mushi/core` event-tracker.ts) returns early
51
+ * without `window`, so RN gets this minimal port: in-memory batch, interval
52
+ * flush, explicit `flush()` for app-background, AsyncStorage spill for
53
+ * unsent batches (cap 200 / 24 h) and persisted consent.
54
+ * - Validation and PII rules are the shared ones from core
55
+ * (`isValidEventName`, `sanitizeEventProperties`, `propertiesWithinByteLimit`).
56
+ * - Transport is `MushiApiClient.postProductEvents()` — the same
57
+ * POST /v1/sdk/events the web SDK uses; `surface` is `'mobile'`.
58
+ *
59
+ * DEPENDENCIES:
60
+ * - @mushi-mushi/core — validation helpers + wire types.
61
+ * - @react-native-async-storage/async-storage — optional peer; without it the
62
+ * batch is memory-only and consent is per-launch.
63
+ *
64
+ * USAGE:
65
+ * - Created by MushiProvider; hosts call `useMushi().track(name, props)`.
66
+ * - No React import here so the module is unit-testable with fake timers.
67
+ *
68
+ * NOTES:
69
+ * - No DNT signal exists on native; `analytics.enabled:false` or
70
+ * `analytics.consent:'required'` + `setConsent('denied')` are the off switches.
71
+ * App Tracking Transparency prompts remain the host's responsibility.
72
+ */
73
+
74
+ /** The subset of the web `analytics` block that applies on native. */
75
+ type RNAnalyticsConfig = Pick<MushiAnalyticsConfig, 'enabled' | 'consent' | 'flushIntervalMs' | 'propertyAllowlist'>;
76
+
45
77
  interface MushiRNConfig {
46
78
  projectId: string;
47
79
  apiKey: string;
@@ -115,6 +147,22 @@ interface MushiRNConfig {
115
147
  secureStorage?: boolean;
116
148
  };
117
149
  rewards?: MushiRewardsConfig;
150
+ /**
151
+ * Product analytics (`useMushi().track()`). Events batch to
152
+ * POST /v1/sdk/events every 5 s, on app background and at 20 queued events;
153
+ * unsent batches spill to AsyncStorage (optional peer) and replay on the
154
+ * next launch. `consent: 'required'` buffers until `setConsent('granted')`.
155
+ * There is no DNT signal on native — `enabled: false` is the off switch.
156
+ */
157
+ analytics?: RNAnalyticsConfig;
158
+ /**
159
+ * Session lifecycle tracking for the console's Activity and Users views:
160
+ * session start / end on foreground and background, a heartbeat every
161
+ * minute, and a page view per `setScreen()` change. Default true. Follows
162
+ * the `analytics` switch and consent: nothing is sent while analytics is
163
+ * disabled or consent is not granted.
164
+ */
165
+ trackSessions?: boolean;
118
166
  }
119
167
 
120
168
  interface MushiRNInstance {
@@ -128,7 +176,11 @@ interface MushiRNInstance {
128
176
  description: string;
129
177
  category: string;
130
178
  screenshotDataUrl?: string;
131
- }): Promise<void>;
179
+ }): Promise<{
180
+ ok: boolean;
181
+ queued?: boolean;
182
+ failureKind?: 'offline' | 'retrying' | 'rate_limited' | 'quota' | 'permanent' | 'credentials';
183
+ }>;
132
184
  getDeviceInfo(): ReturnType<typeof getDeviceInfo>;
133
185
  getConsoleEntries(): ReturnType<ReturnType<typeof setupConsoleCapture>['getEntries']>;
134
186
  getNetworkEntries(): ReturnType<ReturnType<typeof setupNetworkCapture>['getEntries']>;
@@ -186,6 +238,15 @@ interface MushiRNInstance {
186
238
  getHallOfFame(limit?: number): Promise<MushiHallOfFameEntry[]>;
187
239
  /** Manually record a host-defined activity event. */
188
240
  recordActivity(action: string, metadata?: Record<string, unknown>): void;
241
+ /**
242
+ * Record a product-analytics event, e.g. `track('checkout_started', { plan: 'pro' })`.
243
+ * Names must match `^[a-z][a-z0-9_]{1,63}$`; properties are flat, PII-looking
244
+ * keys are dropped and string values are scrubbed. Batched to
245
+ * POST /v1/sdk/events with `$surface: 'mobile'`. Returns true when queued.
246
+ */
247
+ track(event: string, properties?: Record<string, MushiPropertyValue>): boolean;
248
+ /** Grant or deny analytics consent (persisted in AsyncStorage when available). */
249
+ setConsent(state: 'granted' | 'denied'): void;
189
250
  /** Returns the current user's tier. */
190
251
  getTier(): Promise<MushiTierResult | null>;
191
252
  /** Returns the current user's reputation + point totals. */
@@ -386,4 +447,4 @@ declare class AsyncStorageQueue {
386
447
  private getAsyncStorage;
387
448
  }
388
449
 
389
- export { AsyncStorageQueue, type ConsoleEntry, type DeviceInfo, MUSHI_BANNER_DEFAULT_HEIGHT, MushiBanner, type MushiBannerProps, MushiBottomSheet, type MushiBottomSheetProps, MushiFloatingButton, type MushiFloatingButtonProps, MushiProvider, type MushiRNConfig, type MushiRNInstance, MushiTrigger, type MushiTriggerProps, type NavigationEntry, type NetworkEntry, getDeviceInfo, setupConsoleCapture, setupNetworkCapture, useMushi, useMushiReport, useMushiWidget, useNavigationCapture };
450
+ export { AsyncStorageQueue, type ConsoleEntry, type DeviceInfo, MUSHI_BANNER_DEFAULT_HEIGHT, MushiBanner, type MushiBannerProps, MushiBottomSheet, type MushiBottomSheetProps, MushiFloatingButton, type MushiFloatingButtonProps, MushiProvider, type MushiRNConfig, type MushiRNInstance, MushiTrigger, type MushiTriggerProps, type NavigationEntry, type NetworkEntry, type RNAnalyticsConfig, getDeviceInfo, setupConsoleCapture, setupNetworkCapture, useMushi, useMushiReport, useMushiWidget, useNavigationCapture };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, FC, ReactElement } from 'react';
3
- import { MushiRewardsConfig, MushiPageContext, MushiBreadcrumb, MushiReporterReport, MushiReporterComment, MushiHallOfFameEntry, MushiTierResult, MushiReputationResult, MushiAssistantReply } from '@mushi-mushi/core';
3
+ import { MushiAnalyticsConfig, MushiRewardsConfig, MushiPageContext, MushiBreadcrumb, MushiReporterReport, MushiReporterComment, MushiHallOfFameEntry, MushiPropertyValue, MushiTierResult, MushiReputationResult, MushiAssistantReply } from '@mushi-mushi/core';
4
4
  export { MushiHallOfFameEntry, MushiReporterComment, MushiReporterReport } from '@mushi-mushi/core';
5
5
 
6
6
  interface ConsoleEntry {
@@ -42,6 +42,38 @@ interface DeviceInfo {
42
42
  }
43
43
  declare function getDeviceInfo(): DeviceInfo;
44
44
 
45
+ /**
46
+ * FILE: packages/react-native/src/analytics/event-tracker.ts
47
+ * PURPOSE: Product-analytics batcher behind `useMushi().track()` on React Native.
48
+ *
49
+ * OVERVIEW:
50
+ * - The core tracker (`@mushi-mushi/core` event-tracker.ts) returns early
51
+ * without `window`, so RN gets this minimal port: in-memory batch, interval
52
+ * flush, explicit `flush()` for app-background, AsyncStorage spill for
53
+ * unsent batches (cap 200 / 24 h) and persisted consent.
54
+ * - Validation and PII rules are the shared ones from core
55
+ * (`isValidEventName`, `sanitizeEventProperties`, `propertiesWithinByteLimit`).
56
+ * - Transport is `MushiApiClient.postProductEvents()` — the same
57
+ * POST /v1/sdk/events the web SDK uses; `surface` is `'mobile'`.
58
+ *
59
+ * DEPENDENCIES:
60
+ * - @mushi-mushi/core — validation helpers + wire types.
61
+ * - @react-native-async-storage/async-storage — optional peer; without it the
62
+ * batch is memory-only and consent is per-launch.
63
+ *
64
+ * USAGE:
65
+ * - Created by MushiProvider; hosts call `useMushi().track(name, props)`.
66
+ * - No React import here so the module is unit-testable with fake timers.
67
+ *
68
+ * NOTES:
69
+ * - No DNT signal exists on native; `analytics.enabled:false` or
70
+ * `analytics.consent:'required'` + `setConsent('denied')` are the off switches.
71
+ * App Tracking Transparency prompts remain the host's responsibility.
72
+ */
73
+
74
+ /** The subset of the web `analytics` block that applies on native. */
75
+ type RNAnalyticsConfig = Pick<MushiAnalyticsConfig, 'enabled' | 'consent' | 'flushIntervalMs' | 'propertyAllowlist'>;
76
+
45
77
  interface MushiRNConfig {
46
78
  projectId: string;
47
79
  apiKey: string;
@@ -115,6 +147,22 @@ interface MushiRNConfig {
115
147
  secureStorage?: boolean;
116
148
  };
117
149
  rewards?: MushiRewardsConfig;
150
+ /**
151
+ * Product analytics (`useMushi().track()`). Events batch to
152
+ * POST /v1/sdk/events every 5 s, on app background and at 20 queued events;
153
+ * unsent batches spill to AsyncStorage (optional peer) and replay on the
154
+ * next launch. `consent: 'required'` buffers until `setConsent('granted')`.
155
+ * There is no DNT signal on native — `enabled: false` is the off switch.
156
+ */
157
+ analytics?: RNAnalyticsConfig;
158
+ /**
159
+ * Session lifecycle tracking for the console's Activity and Users views:
160
+ * session start / end on foreground and background, a heartbeat every
161
+ * minute, and a page view per `setScreen()` change. Default true. Follows
162
+ * the `analytics` switch and consent: nothing is sent while analytics is
163
+ * disabled or consent is not granted.
164
+ */
165
+ trackSessions?: boolean;
118
166
  }
119
167
 
120
168
  interface MushiRNInstance {
@@ -128,7 +176,11 @@ interface MushiRNInstance {
128
176
  description: string;
129
177
  category: string;
130
178
  screenshotDataUrl?: string;
131
- }): Promise<void>;
179
+ }): Promise<{
180
+ ok: boolean;
181
+ queued?: boolean;
182
+ failureKind?: 'offline' | 'retrying' | 'rate_limited' | 'quota' | 'permanent' | 'credentials';
183
+ }>;
132
184
  getDeviceInfo(): ReturnType<typeof getDeviceInfo>;
133
185
  getConsoleEntries(): ReturnType<ReturnType<typeof setupConsoleCapture>['getEntries']>;
134
186
  getNetworkEntries(): ReturnType<ReturnType<typeof setupNetworkCapture>['getEntries']>;
@@ -186,6 +238,15 @@ interface MushiRNInstance {
186
238
  getHallOfFame(limit?: number): Promise<MushiHallOfFameEntry[]>;
187
239
  /** Manually record a host-defined activity event. */
188
240
  recordActivity(action: string, metadata?: Record<string, unknown>): void;
241
+ /**
242
+ * Record a product-analytics event, e.g. `track('checkout_started', { plan: 'pro' })`.
243
+ * Names must match `^[a-z][a-z0-9_]{1,63}$`; properties are flat, PII-looking
244
+ * keys are dropped and string values are scrubbed. Batched to
245
+ * POST /v1/sdk/events with `$surface: 'mobile'`. Returns true when queued.
246
+ */
247
+ track(event: string, properties?: Record<string, MushiPropertyValue>): boolean;
248
+ /** Grant or deny analytics consent (persisted in AsyncStorage when available). */
249
+ setConsent(state: 'granted' | 'denied'): void;
189
250
  /** Returns the current user's tier. */
190
251
  getTier(): Promise<MushiTierResult | null>;
191
252
  /** Returns the current user's reputation + point totals. */
@@ -386,4 +447,4 @@ declare class AsyncStorageQueue {
386
447
  private getAsyncStorage;
387
448
  }
388
449
 
389
- export { AsyncStorageQueue, type ConsoleEntry, type DeviceInfo, MUSHI_BANNER_DEFAULT_HEIGHT, MushiBanner, type MushiBannerProps, MushiBottomSheet, type MushiBottomSheetProps, MushiFloatingButton, type MushiFloatingButtonProps, MushiProvider, type MushiRNConfig, type MushiRNInstance, MushiTrigger, type MushiTriggerProps, type NavigationEntry, type NetworkEntry, getDeviceInfo, setupConsoleCapture, setupNetworkCapture, useMushi, useMushiReport, useMushiWidget, useNavigationCapture };
450
+ export { AsyncStorageQueue, type ConsoleEntry, type DeviceInfo, MUSHI_BANNER_DEFAULT_HEIGHT, MushiBanner, type MushiBannerProps, MushiBottomSheet, type MushiBottomSheetProps, MushiFloatingButton, type MushiFloatingButtonProps, MushiProvider, type MushiRNConfig, type MushiRNInstance, MushiTrigger, type MushiTriggerProps, type NavigationEntry, type NetworkEntry, type RNAnalyticsConfig, getDeviceInfo, setupConsoleCapture, setupNetworkCapture, useMushi, useMushiReport, useMushiWidget, useNavigationCapture };