@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 +25 -5
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +25 -5
- package/package.json +2 -2
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
|
-
|
|
888
|
+
const rawEndpoint = config.apiEndpoint ?? config.endpoint;
|
|
889
|
+
if (rawEndpoint !== void 0 && rawEndpoint.trim() === "") {
|
|
880
890
|
throw new Error(
|
|
881
|
-
"[MushiProvider]
|
|
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
|
-
|
|
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
|
-
|
|
885
|
+
const rawEndpoint = config.apiEndpoint ?? config.endpoint;
|
|
886
|
+
if (rawEndpoint !== void 0 && rawEndpoint.trim() === "") {
|
|
877
887
|
throw new Error(
|
|
878
|
-
"[MushiProvider]
|
|
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
|
-
|
|
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.
|
|
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.
|
|
36
|
+
"@mushi-mushi/core": "^1.12.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"@types/react": "^19.2.14",
|