@mushi-mushi/core 1.9.0 → 1.11.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 +45 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -2
- package/dist/index.d.ts +67 -2
- package/dist/index.js +45 -7
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -140,12 +140,20 @@ function createApiClient(options) {
|
|
|
140
140
|
reporterToken
|
|
141
141
|
);
|
|
142
142
|
},
|
|
143
|
-
async replyToReporterReport(reportId, reporterToken, body) {
|
|
143
|
+
async replyToReporterReport(reportId, reporterToken, body, feedbackSignal) {
|
|
144
144
|
return requestForReporter(
|
|
145
145
|
"POST",
|
|
146
146
|
`/v1/reporter/reports/${reportId}/reply`,
|
|
147
147
|
reporterToken,
|
|
148
|
-
{ body }
|
|
148
|
+
{ body, ...feedbackSignal ? { feedback_signal: feedbackSignal } : {} }
|
|
149
|
+
);
|
|
150
|
+
},
|
|
151
|
+
async reopenReporterReport(reportId, reporterToken, note) {
|
|
152
|
+
return requestForReporter(
|
|
153
|
+
"POST",
|
|
154
|
+
`/v1/reporter/reports/${reportId}/reopen`,
|
|
155
|
+
reporterToken,
|
|
156
|
+
{ note: note ?? "" }
|
|
149
157
|
);
|
|
150
158
|
},
|
|
151
159
|
// ─── Rewards program (P1) ──────────────────────────────────
|
|
@@ -194,6 +202,15 @@ function createApiClient(options) {
|
|
|
194
202
|
1,
|
|
195
203
|
"reporter-poll"
|
|
196
204
|
);
|
|
205
|
+
},
|
|
206
|
+
async getHallOfFame(limit = 10) {
|
|
207
|
+
return request(
|
|
208
|
+
"GET",
|
|
209
|
+
`/v1/sdk/hall-of-fame?limit=${limit}`,
|
|
210
|
+
void 0,
|
|
211
|
+
1,
|
|
212
|
+
"reporter-poll"
|
|
213
|
+
);
|
|
197
214
|
}
|
|
198
215
|
};
|
|
199
216
|
}
|
|
@@ -292,8 +309,10 @@ var SPAM_PATTERNS = [
|
|
|
292
309
|
// numbers only
|
|
293
310
|
/^[^a-zA-Z\u00C0-\u024F\u4E00-\u9FFF\u3040-\u309F\u30A0-\u30FF]{10,}$/,
|
|
294
311
|
// no real letters
|
|
295
|
-
|
|
296
|
-
//
|
|
312
|
+
// "test" removed — users legitimately write "I was testing…" in real reports.
|
|
313
|
+
// Keep clearly-nonsense patterns that are never real sentences.
|
|
314
|
+
/^(asdf|qwerty|lorem ipsum)[.,!?\s]*$/i
|
|
315
|
+
// standalone keyboard-mash or placeholder
|
|
297
316
|
];
|
|
298
317
|
var GIBBERISH_PATTERN = /^[bcdfghjklmnpqrstvwxz]{6,}/i;
|
|
299
318
|
function createPreFilter(config = {}) {
|
|
@@ -583,9 +602,11 @@ var DB_VERSION = 1;
|
|
|
583
602
|
var LS_KEY = "mushi_offline_queue";
|
|
584
603
|
var BATCH_SIZE = 10;
|
|
585
604
|
var MAX_BACKOFF_MS = 6e4;
|
|
605
|
+
var AUTO_FLUSH_INTERVAL_MS = 3e4;
|
|
586
606
|
function createOfflineQueue(config = {}) {
|
|
587
607
|
const { enabled = true, maxQueueSize = 50, syncOnReconnect = true, encryptAtRest = true } = config;
|
|
588
608
|
let syncCleanup = null;
|
|
609
|
+
let flushInterval = null;
|
|
589
610
|
let backendType = null;
|
|
590
611
|
async function wrapForStorage(report) {
|
|
591
612
|
const queuedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -780,6 +801,7 @@ function createOfflineQueue(config = {}) {
|
|
|
780
801
|
const permanent = result.error?.code === "HTTP_400" || result.error?.code === "HTTP_422" || result.error?.code === "INGEST_ERROR" || result.error?.code === "VALIDATION_ERROR" || typeof result.error?.message === "string" && /invalid payload|description must be at least|validation/i.test(
|
|
781
802
|
result.error.message
|
|
782
803
|
);
|
|
804
|
+
const transient = !permanent && (result.error?.code === "NETWORK_ERROR" || result.error?.code === "HTTP_403" || result.error?.code === "HTTP_429" || result.error?.code === "HTTP_502" || result.error?.code === "HTTP_503" || result.error?.code === "HTTP_504" || typeof result.error?.code === "string" && result.error.code.startsWith("HTTP_5"));
|
|
783
805
|
if (permanent) {
|
|
784
806
|
try {
|
|
785
807
|
if (backend === "indexeddb") await idbDelete(rowId);
|
|
@@ -787,6 +809,11 @@ function createOfflineQueue(config = {}) {
|
|
|
787
809
|
} catch {
|
|
788
810
|
lsDelete(rowId);
|
|
789
811
|
}
|
|
812
|
+
} else if (transient) {
|
|
813
|
+
queueLog.debug("Offline queue: transient failure, will retry", {
|
|
814
|
+
id: rowId,
|
|
815
|
+
code: result.error?.code
|
|
816
|
+
});
|
|
790
817
|
}
|
|
791
818
|
failed++;
|
|
792
819
|
if (i < batch.length - 1) {
|
|
@@ -822,14 +849,25 @@ function createOfflineQueue(config = {}) {
|
|
|
822
849
|
}
|
|
823
850
|
function startAutoSync(client) {
|
|
824
851
|
if (!enabled || !syncOnReconnect || typeof window === "undefined") return;
|
|
825
|
-
const
|
|
852
|
+
const tryFlush = () => {
|
|
826
853
|
if (navigator.onLine) {
|
|
827
854
|
flush(client).catch(() => {
|
|
828
855
|
});
|
|
829
856
|
}
|
|
830
857
|
};
|
|
831
|
-
window.addEventListener("online",
|
|
832
|
-
|
|
858
|
+
window.addEventListener("online", tryFlush);
|
|
859
|
+
flushInterval = setInterval(() => {
|
|
860
|
+
void size().then((n) => {
|
|
861
|
+
if (n > 0) tryFlush();
|
|
862
|
+
});
|
|
863
|
+
}, AUTO_FLUSH_INTERVAL_MS);
|
|
864
|
+
syncCleanup = () => {
|
|
865
|
+
window.removeEventListener("online", tryFlush);
|
|
866
|
+
if (flushInterval) {
|
|
867
|
+
clearInterval(flushInterval);
|
|
868
|
+
flushInterval = null;
|
|
869
|
+
}
|
|
870
|
+
};
|
|
833
871
|
}
|
|
834
872
|
function stopAutoSync() {
|
|
835
873
|
syncCleanup?.();
|