@mushi-mushi/react-native 0.15.0 → 0.15.1

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
@@ -170,10 +170,12 @@ var AsyncStorageQueue = class {
170
170
  maxSize;
171
171
  apiEndpoint;
172
172
  apiKey;
173
+ onSynced;
173
174
  constructor(config) {
174
175
  this.maxSize = config.maxSize ?? 50;
175
176
  this.apiEndpoint = config.apiEndpoint;
176
177
  this.apiKey = config.apiKey;
178
+ this.onSynced = config.onSynced;
177
179
  }
178
180
  async enqueue(report) {
179
181
  const AsyncStorage = await this.getAsyncStorage();
@@ -195,6 +197,13 @@ var AsyncStorageQueue = class {
195
197
  const ok = await sendWithRetry(item, this.apiEndpoint, this.apiKey);
196
198
  if (ok) {
197
199
  flushed++;
200
+ const reportId = item.report.id;
201
+ if (typeof reportId === "string") {
202
+ try {
203
+ this.onSynced?.(reportId);
204
+ } catch {
205
+ }
206
+ }
198
207
  } else {
199
208
  remaining.push(item);
200
209
  break;
@@ -876,12 +885,16 @@ function MushiProvider({ children, ...config }) {
876
885
  resolveReporterTokenReady = resolve;
877
886
  })
878
887
  );
879
- if (config.endpoint !== void 0 && config.endpoint.trim() === "") {
888
+ const rawEndpoint = config.apiEndpoint ?? config.endpoint;
889
+ if (rawEndpoint !== void 0 && rawEndpoint.trim() === "") {
880
890
  throw new Error(
881
- "[MushiProvider] endpoint is set to an empty string. Set endpoint to your Supabase edge function URL, e.g. https://xyz.supabase.co/functions/v1/api, or omit it to use the cloud default."
891
+ "[MushiProvider] apiEndpoint is set to an empty string. Set apiEndpoint to your Supabase edge function URL, e.g. https://xyz.supabase.co/functions/v1/api, or omit it to use the cloud default."
882
892
  );
883
893
  }
884
- const apiEndpoint = config.endpoint ?? import_core.DEFAULT_API_ENDPOINT;
894
+ if (config.endpoint && !config.apiEndpoint && __DEV__) {
895
+ console.warn("[MushiProvider] `endpoint` is deprecated \u2014 use `apiEndpoint` instead.");
896
+ }
897
+ const apiEndpoint = rawEndpoint ?? import_core.DEFAULT_API_ENDPOINT;
885
898
  (0, import_react3.useEffect)(() => {
886
899
  if (config.capture?.console !== false) {
887
900
  consoleRef.current = setupConsoleCapture(config.capture?.maxConsoleEntries);
@@ -897,7 +910,11 @@ function MushiProvider({ children, ...config }) {
897
910
  queueRef.current = new AsyncStorageQueue({
898
911
  maxSize: config.storage?.maxQueueSize,
899
912
  apiEndpoint,
900
- apiKey: config.apiKey
913
+ apiKey: config.apiKey,
914
+ // `onReportSynced` fires here — when a previously-queued report actually
915
+ // drains to the server — not on the direct-submit path (where it would be
916
+ // indistinguishable from `onReportSubmitted` and thus meaningless).
917
+ onSynced: (reportId) => config.callbacks?.onReportSynced?.(reportId)
901
918
  });
902
919
  queueRef.current.flush().catch(() => {
903
920
  });
@@ -1031,9 +1048,12 @@ function MushiProvider({ children, ...config }) {
1031
1048
  const result = await client.submitReport(report);
1032
1049
  if (!result.ok) {
1033
1050
  await queueRef.current?.enqueue(report);
1051
+ config.callbacks?.onReportQueued?.(report.id);
1052
+ } else {
1053
+ config.callbacks?.onReportSubmitted?.(report.id);
1034
1054
  }
1035
1055
  },
1036
- [config.projectId, apiEndpoint]
1056
+ [config.projectId, config.callbacks, apiEndpoint]
1037
1057
  );
1038
1058
  const userRef = (0, import_react3.useRef)(null);
1039
1059
  const metadataRef = (0, import_react3.useRef)({});
package/dist/index.d.cts CHANGED
@@ -46,7 +46,18 @@ declare function getDeviceInfo(): DeviceInfo;
46
46
  interface MushiRNConfig {
47
47
  projectId: string;
48
48
  apiKey: string;
49
+ /** @deprecated Prefer `apiEndpoint` — kept for backward compatibility */
49
50
  endpoint?: string;
51
+ /** Canonical Mushi API base URL (e.g. https://xyz.supabase.co/functions/v1/api) */
52
+ apiEndpoint?: string;
53
+ /** Lifecycle callbacks for host-app integration (replaces polling in HHTP etc.) */
54
+ callbacks?: {
55
+ onReportSubmitted?: (reportId: string) => void;
56
+ onReportQueued?: (reportId: string) => void;
57
+ onReportSynced?: (reportId: string) => void;
58
+ onReporterReply?: (reportId: string, commentId: string) => void;
59
+ onFixStatusChanged?: (reportId: string, status: string) => void;
60
+ };
50
61
  widget?: {
51
62
  trigger?: 'shake' | 'button' | 'both' | 'manual' | 'auto' | 'edge-tab' | 'hidden' | 'attach';
52
63
  shakeThreshold?: number;
@@ -240,10 +251,13 @@ declare class AsyncStorageQueue {
240
251
  private maxSize;
241
252
  private apiEndpoint;
242
253
  private apiKey;
254
+ private onSynced?;
243
255
  constructor(config: {
244
256
  maxSize?: number;
245
257
  apiEndpoint: string;
246
258
  apiKey: string;
259
+ /** Fired once per queued report that drains successfully to the server. */
260
+ onSynced?: (reportId: string) => void;
247
261
  });
248
262
  enqueue(report: object): Promise<void>;
249
263
  flush(): Promise<number>;
package/dist/index.d.ts CHANGED
@@ -46,7 +46,18 @@ declare function getDeviceInfo(): DeviceInfo;
46
46
  interface MushiRNConfig {
47
47
  projectId: string;
48
48
  apiKey: string;
49
+ /** @deprecated Prefer `apiEndpoint` — kept for backward compatibility */
49
50
  endpoint?: string;
51
+ /** Canonical Mushi API base URL (e.g. https://xyz.supabase.co/functions/v1/api) */
52
+ apiEndpoint?: string;
53
+ /** Lifecycle callbacks for host-app integration (replaces polling in HHTP etc.) */
54
+ callbacks?: {
55
+ onReportSubmitted?: (reportId: string) => void;
56
+ onReportQueued?: (reportId: string) => void;
57
+ onReportSynced?: (reportId: string) => void;
58
+ onReporterReply?: (reportId: string, commentId: string) => void;
59
+ onFixStatusChanged?: (reportId: string, status: string) => void;
60
+ };
50
61
  widget?: {
51
62
  trigger?: 'shake' | 'button' | 'both' | 'manual' | 'auto' | 'edge-tab' | 'hidden' | 'attach';
52
63
  shakeThreshold?: number;
@@ -240,10 +251,13 @@ declare class AsyncStorageQueue {
240
251
  private maxSize;
241
252
  private apiEndpoint;
242
253
  private apiKey;
254
+ private onSynced?;
243
255
  constructor(config: {
244
256
  maxSize?: number;
245
257
  apiEndpoint: string;
246
258
  apiKey: string;
259
+ /** Fired once per queued report that drains successfully to the server. */
260
+ onSynced?: (reportId: string) => void;
247
261
  });
248
262
  enqueue(report: object): Promise<void>;
249
263
  flush(): Promise<number>;
package/dist/index.js CHANGED
@@ -142,10 +142,12 @@ var AsyncStorageQueue = class {
142
142
  maxSize;
143
143
  apiEndpoint;
144
144
  apiKey;
145
+ onSynced;
145
146
  constructor(config) {
146
147
  this.maxSize = config.maxSize ?? 50;
147
148
  this.apiEndpoint = config.apiEndpoint;
148
149
  this.apiKey = config.apiKey;
150
+ this.onSynced = config.onSynced;
149
151
  }
150
152
  async enqueue(report) {
151
153
  const AsyncStorage = await this.getAsyncStorage();
@@ -167,6 +169,13 @@ var AsyncStorageQueue = class {
167
169
  const ok = await sendWithRetry(item, this.apiEndpoint, this.apiKey);
168
170
  if (ok) {
169
171
  flushed++;
172
+ const reportId = item.report.id;
173
+ if (typeof reportId === "string") {
174
+ try {
175
+ this.onSynced?.(reportId);
176
+ } catch {
177
+ }
178
+ }
170
179
  } else {
171
180
  remaining.push(item);
172
181
  break;
@@ -873,12 +882,16 @@ function MushiProvider({ children, ...config }) {
873
882
  resolveReporterTokenReady = resolve;
874
883
  })
875
884
  );
876
- if (config.endpoint !== void 0 && config.endpoint.trim() === "") {
885
+ const rawEndpoint = config.apiEndpoint ?? config.endpoint;
886
+ if (rawEndpoint !== void 0 && rawEndpoint.trim() === "") {
877
887
  throw new Error(
878
- "[MushiProvider] endpoint is set to an empty string. Set endpoint to your Supabase edge function URL, e.g. https://xyz.supabase.co/functions/v1/api, or omit it to use the cloud default."
888
+ "[MushiProvider] apiEndpoint is set to an empty string. Set apiEndpoint to your Supabase edge function URL, e.g. https://xyz.supabase.co/functions/v1/api, or omit it to use the cloud default."
879
889
  );
880
890
  }
881
- const apiEndpoint = config.endpoint ?? DEFAULT_API_ENDPOINT;
891
+ if (config.endpoint && !config.apiEndpoint && __DEV__) {
892
+ console.warn("[MushiProvider] `endpoint` is deprecated \u2014 use `apiEndpoint` instead.");
893
+ }
894
+ const apiEndpoint = rawEndpoint ?? DEFAULT_API_ENDPOINT;
882
895
  useEffect2(() => {
883
896
  if (config.capture?.console !== false) {
884
897
  consoleRef.current = setupConsoleCapture(config.capture?.maxConsoleEntries);
@@ -894,7 +907,11 @@ function MushiProvider({ children, ...config }) {
894
907
  queueRef.current = new AsyncStorageQueue({
895
908
  maxSize: config.storage?.maxQueueSize,
896
909
  apiEndpoint,
897
- apiKey: config.apiKey
910
+ apiKey: config.apiKey,
911
+ // `onReportSynced` fires here — when a previously-queued report actually
912
+ // drains to the server — not on the direct-submit path (where it would be
913
+ // indistinguishable from `onReportSubmitted` and thus meaningless).
914
+ onSynced: (reportId) => config.callbacks?.onReportSynced?.(reportId)
898
915
  });
899
916
  queueRef.current.flush().catch(() => {
900
917
  });
@@ -1028,9 +1045,12 @@ function MushiProvider({ children, ...config }) {
1028
1045
  const result = await client.submitReport(report);
1029
1046
  if (!result.ok) {
1030
1047
  await queueRef.current?.enqueue(report);
1048
+ config.callbacks?.onReportQueued?.(report.id);
1049
+ } else {
1050
+ config.callbacks?.onReportSubmitted?.(report.id);
1031
1051
  }
1032
1052
  },
1033
- [config.projectId, apiEndpoint]
1053
+ [config.projectId, config.callbacks, apiEndpoint]
1034
1054
  );
1035
1055
  const userRef = useRef3(null);
1036
1056
  const metadataRef = useRef3({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mushi-mushi/react-native",
3
- "version": "0.15.0",
3
+ "version": "0.15.1",
4
4
  "license": "MIT",
5
5
  "description": "React Native SDK for Mushi Mushi — shake-to-report, bottom sheet widget, full context capture",
6
6
  "main": "./dist/index.js",
@@ -33,7 +33,7 @@
33
33
  }
34
34
  },
35
35
  "dependencies": {
36
- "@mushi-mushi/core": "^1.11.0"
36
+ "@mushi-mushi/core": "^1.12.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/react": "^19.2.14",