@mushi-mushi/core 1.21.0 → 1.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/README.md +4 -2
- package/dist/index.cjs +45 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +42 -1
- package/dist/index.d.ts +42 -1
- package/dist/index.js +44 -8
- package/dist/index.js.map +1 -1
- package/package.json +9 -10
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @mushi-mushi/core
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **Your AI wrote it. Mushi tells you why it broke.**
|
|
4
|
+
|
|
5
|
+
Core types, API client, and shared utilities for every Mushi SDK package.
|
|
4
6
|
|
|
5
7
|
> **You almost certainly don't need to install this directly.** Run `npx mushi-mushi` and the wizard will pick the right framework SDK ([`@mushi-mushi/react`](https://npmjs.com/package/@mushi-mushi/react), [`@mushi-mushi/vue`](https://npmjs.com/package/@mushi-mushi/vue), [`@mushi-mushi/svelte`](https://npmjs.com/package/@mushi-mushi/svelte), [`@mushi-mushi/angular`](https://npmjs.com/package/@mushi-mushi/angular), [`@mushi-mushi/react-native`](https://npmjs.com/package/@mushi-mushi/react-native), [`@mushi-mushi/capacitor`](https://npmjs.com/package/@mushi-mushi/capacitor), or [`@mushi-mushi/web`](https://npmjs.com/package/@mushi-mushi/web)) which depends on this package.
|
|
6
8
|
|
|
@@ -70,4 +72,4 @@ MIT
|
|
|
70
72
|
<!-- mushi-readme-stats-footer -->
|
|
71
73
|
---
|
|
72
74
|
|
|
73
|
-
<sub>Monorepo scale (June 2026):
|
|
75
|
+
<sub>Monorepo scale (June 2026): 51 edge functions · 298 SQL migrations · 13 outbound plugins · 11 inbound adapters · 19 pipeline agents. Canonical counts: <a href="https://github.com/kensaurus/mushi-mushi/blob/master/docs/stats.md">docs/stats.md</a> · <code>pnpm docs-stats</code></sub>
|
package/dist/index.cjs
CHANGED
|
@@ -106,6 +106,8 @@ var MUSHI_INTERNAL_HEADER = "X-Mushi-Internal";
|
|
|
106
106
|
var MUSHI_INTERNAL_INIT_MARKER = "__mushiInternal";
|
|
107
107
|
var DEFAULT_TIMEOUT = 1e4;
|
|
108
108
|
var DEFAULT_MAX_RETRIES = 2;
|
|
109
|
+
var DEFAULT_CIRCUIT_THRESHOLD = 4;
|
|
110
|
+
var DEFAULT_CIRCUIT_COOLDOWN_MS = 3e4;
|
|
109
111
|
function createApiClient(options) {
|
|
110
112
|
const {
|
|
111
113
|
projectId,
|
|
@@ -115,10 +117,29 @@ function createApiClient(options) {
|
|
|
115
117
|
maxRetries = DEFAULT_MAX_RETRIES,
|
|
116
118
|
getUserToken,
|
|
117
119
|
sdkPackage,
|
|
118
|
-
sdkVersion
|
|
120
|
+
sdkVersion,
|
|
121
|
+
circuitBreaker
|
|
119
122
|
} = options;
|
|
120
123
|
let baseUrl = apiEndpoint.replace(/\/$/, "");
|
|
124
|
+
const cbEnabled = circuitBreaker?.enabled !== false;
|
|
125
|
+
const cbThreshold = Math.max(1, circuitBreaker?.threshold ?? DEFAULT_CIRCUIT_THRESHOLD);
|
|
126
|
+
const cbCooldownMs = Math.max(1e3, circuitBreaker?.cooldownMs ?? DEFAULT_CIRCUIT_COOLDOWN_MS);
|
|
127
|
+
let cbFailures = 0;
|
|
128
|
+
let cbOpenUntil = 0;
|
|
129
|
+
const cbIsOpen = () => cbEnabled && cbOpenUntil > Date.now();
|
|
130
|
+
const cbRecordReachable = () => {
|
|
131
|
+
cbFailures = 0;
|
|
132
|
+
cbOpenUntil = 0;
|
|
133
|
+
};
|
|
134
|
+
const cbRecordUnreachable = () => {
|
|
135
|
+
if (!cbEnabled) return;
|
|
136
|
+
cbFailures += 1;
|
|
137
|
+
if (cbFailures >= cbThreshold) cbOpenUntil = Date.now() + cbCooldownMs;
|
|
138
|
+
};
|
|
121
139
|
async function request(method, path, body, retries = maxRetries, internalKind, extraHeaders) {
|
|
140
|
+
if (cbIsOpen()) {
|
|
141
|
+
return { ok: false, error: { code: "CIRCUIT_OPEN", message: "Endpoint temporarily unavailable; retrying later." } };
|
|
142
|
+
}
|
|
122
143
|
const url = `${baseUrl}${path}`;
|
|
123
144
|
const controller = new AbortController();
|
|
124
145
|
const timer = setTimeout(() => controller.abort(), timeout);
|
|
@@ -165,6 +186,8 @@ function createApiClient(options) {
|
|
|
165
186
|
await sleep(getBackoffDelay(maxRetries - retries));
|
|
166
187
|
return request(method, path, body, retries - 1, internalKind, extraHeaders);
|
|
167
188
|
}
|
|
189
|
+
if (response.status >= 500) cbRecordUnreachable();
|
|
190
|
+
else cbRecordReachable();
|
|
168
191
|
return {
|
|
169
192
|
ok: false,
|
|
170
193
|
error: {
|
|
@@ -175,6 +198,7 @@ function createApiClient(options) {
|
|
|
175
198
|
}
|
|
176
199
|
const payload = await response.json();
|
|
177
200
|
const data = payload && typeof payload === "object" && "ok" in payload && "data" in payload ? payload.data : payload;
|
|
201
|
+
cbRecordReachable();
|
|
178
202
|
return { ok: true, data };
|
|
179
203
|
} catch (error) {
|
|
180
204
|
clearTimeout(timer);
|
|
@@ -182,6 +206,7 @@ function createApiClient(options) {
|
|
|
182
206
|
await sleep(getBackoffDelay(maxRetries - retries));
|
|
183
207
|
return request(method, path, body, retries - 1, internalKind);
|
|
184
208
|
}
|
|
209
|
+
cbRecordUnreachable();
|
|
185
210
|
return {
|
|
186
211
|
ok: false,
|
|
187
212
|
error: {
|
|
@@ -466,9 +491,9 @@ function isRetryable(error) {
|
|
|
466
491
|
|
|
467
492
|
// src/region.ts
|
|
468
493
|
var REGION_ENDPOINTS = {
|
|
469
|
-
us: "https://
|
|
470
|
-
eu: "https://
|
|
471
|
-
jp: "https://
|
|
494
|
+
us: "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api",
|
|
495
|
+
eu: "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api",
|
|
496
|
+
jp: "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api"
|
|
472
497
|
};
|
|
473
498
|
var ROUTING_CACHE_KEY = "mushi_region_v1";
|
|
474
499
|
var ROUTING_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -1214,7 +1239,8 @@ function createOfflineQueue(config = {}) {
|
|
|
1214
1239
|
if (!enabled || !syncOnReconnect || typeof window === "undefined") return;
|
|
1215
1240
|
const tryFlush = () => {
|
|
1216
1241
|
if (navigator.onLine) {
|
|
1217
|
-
flush(client).catch(() => {
|
|
1242
|
+
flush(client).catch((err) => {
|
|
1243
|
+
queueLog.warn("Offline queue auto-flush failed", { err: String(err) });
|
|
1218
1244
|
});
|
|
1219
1245
|
}
|
|
1220
1246
|
};
|
|
@@ -1247,6 +1273,15 @@ function captureEnvironment() {
|
|
|
1247
1273
|
const scr = typeof screen !== "undefined" ? screen : void 0;
|
|
1248
1274
|
void kickOffUserAgentData(nav);
|
|
1249
1275
|
const connection = nav && "connection" in nav ? nav.connection : void 0;
|
|
1276
|
+
const w = win;
|
|
1277
|
+
const isCapacitor = !!w?.Capacitor;
|
|
1278
|
+
const isCordova = !!w?.cordova;
|
|
1279
|
+
const isReactNative = nav?.product === "ReactNative" || typeof globalThis.HermesInternal !== "undefined";
|
|
1280
|
+
const native = isCapacitor || isCordova || isReactNative ? {
|
|
1281
|
+
...isCapacitor ? { capacitor: true } : {},
|
|
1282
|
+
...isCordova ? { cordova: true } : {},
|
|
1283
|
+
...isReactNative ? { reactNative: true } : {}
|
|
1284
|
+
} : void 0;
|
|
1250
1285
|
return {
|
|
1251
1286
|
userAgent: nav?.userAgent ?? "unknown",
|
|
1252
1287
|
platform: nav?.platform ?? "unknown",
|
|
@@ -1279,7 +1314,8 @@ function captureEnvironment() {
|
|
|
1279
1314
|
displayMode: matchDisplayMode(win),
|
|
1280
1315
|
documentTitle: doc?.title?.slice(0, 200),
|
|
1281
1316
|
buildId: readBuildIdMeta(doc),
|
|
1282
|
-
pageLoadTiming: capturePageLoadTiming(win)
|
|
1317
|
+
pageLoadTiming: capturePageLoadTiming(win),
|
|
1318
|
+
...native ? { native } : {}
|
|
1283
1319
|
};
|
|
1284
1320
|
}
|
|
1285
1321
|
function findNearestTestidFromActive(doc) {
|
|
@@ -1933,7 +1969,7 @@ var SLUG_DOMAIN_HINTS = {
|
|
|
1933
1969
|
"glot-it": "glot.it",
|
|
1934
1970
|
glotit: "glot.it",
|
|
1935
1971
|
"solo-boss-cloud": "sbc-front.vercel.app",
|
|
1936
|
-
"mushi-mushi": "
|
|
1972
|
+
"mushi-mushi": "kensaur.us"
|
|
1937
1973
|
};
|
|
1938
1974
|
var SLUG_ICON_URL_HINTS = {
|
|
1939
1975
|
"mushi-mushi": "https://kensaur.us/mushi-mushi/admin/favicon.svg",
|
|
@@ -2112,6 +2148,8 @@ function isSafeFaviconHref(href) {
|
|
|
2112
2148
|
}
|
|
2113
2149
|
|
|
2114
2150
|
exports.DEFAULT_API_ENDPOINT = DEFAULT_API_ENDPOINT;
|
|
2151
|
+
exports.DEFAULT_MAX_RETRIES = DEFAULT_MAX_RETRIES;
|
|
2152
|
+
exports.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT;
|
|
2115
2153
|
exports.MAX_REPORT_PAYLOAD_BYTES = MAX_REPORT_PAYLOAD_BYTES;
|
|
2116
2154
|
exports.MAX_SCREENSHOT_DATA_URL_BYTES = MAX_SCREENSHOT_DATA_URL_BYTES;
|
|
2117
2155
|
exports.MUSHI_ACCENT_SHADOW = MUSHI_ACCENT_SHADOW;
|