connectbase-client 4.4.1 → 5.0.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/CHANGELOG.md +50 -0
- package/dist/connect-base.umd.js +5 -5
- package/dist/index.d.mts +114 -3
- package/dist/index.d.ts +114 -3
- package/dist/index.js +195 -56
- package/dist/index.mjs +193 -56
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -116,6 +116,123 @@ var AdsAPI = class {
|
|
|
116
116
|
}
|
|
117
117
|
};
|
|
118
118
|
|
|
119
|
+
// src/types/error.ts
|
|
120
|
+
var ApiError = class extends Error {
|
|
121
|
+
constructor(statusCode, message, code, details) {
|
|
122
|
+
super(message);
|
|
123
|
+
this.statusCode = statusCode;
|
|
124
|
+
this.name = "ApiError";
|
|
125
|
+
this.code = code;
|
|
126
|
+
this.details = details;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* `JSON.stringify(err)` 가 `{}` 로 찍히지 않게 한다.
|
|
130
|
+
*
|
|
131
|
+
* 표준 `Error` 는 message/stack 이 non-enumerable 이라 JSON 직렬화 시 빈 객체가
|
|
132
|
+
* 된다. 로그를 `JSON.stringify` 로 남기는 소비자에게는 "에러 정보가 아무것도 안
|
|
133
|
+
* 온다"로 보여, 실제로는 있는 정보까지 없는 것으로 오진하게 만든다
|
|
134
|
+
* (platform-issue 019fa21c).
|
|
135
|
+
*/
|
|
136
|
+
toJSON() {
|
|
137
|
+
return {
|
|
138
|
+
name: this.name,
|
|
139
|
+
message: this.message,
|
|
140
|
+
code: this.code,
|
|
141
|
+
statusCode: this.statusCode,
|
|
142
|
+
details: this.details
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
var AIError = class extends Error {
|
|
147
|
+
constructor(init) {
|
|
148
|
+
super(init.message || init.code || "AI request failed");
|
|
149
|
+
this.name = "AIError";
|
|
150
|
+
this.code = init.code || "stream_failed";
|
|
151
|
+
this.retryable = init.retryable ?? isRetryableAICode(this.code);
|
|
152
|
+
this.status = init.status;
|
|
153
|
+
this.provider = init.provider;
|
|
154
|
+
this.model = init.model;
|
|
155
|
+
this.retryAfter = init.retryAfter;
|
|
156
|
+
this.detailCode = init.detailCode;
|
|
157
|
+
this.sessionId = init.sessionId;
|
|
158
|
+
}
|
|
159
|
+
/** `JSON.stringify(err)` 가 `{}` 가 되지 않도록 한다 (ApiError.toJSON 참조). */
|
|
160
|
+
toJSON() {
|
|
161
|
+
return {
|
|
162
|
+
name: this.name,
|
|
163
|
+
code: this.code,
|
|
164
|
+
message: this.message,
|
|
165
|
+
retryable: this.retryable,
|
|
166
|
+
status: this.status,
|
|
167
|
+
provider: this.provider,
|
|
168
|
+
model: this.model,
|
|
169
|
+
retryAfter: this.retryAfter,
|
|
170
|
+
detailCode: this.detailCode,
|
|
171
|
+
sessionId: this.sessionId
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
function isRetryableAICode(code) {
|
|
176
|
+
return code === "provider_timeout" || code === "service_unavailable" || code === "rate_limit_exceeded" || code === "stream_failed";
|
|
177
|
+
}
|
|
178
|
+
function toAIError(payload, fallback) {
|
|
179
|
+
if (payload instanceof AIError) return payload;
|
|
180
|
+
const p = typeof payload === "object" && payload !== null ? payload : {};
|
|
181
|
+
const str = (v) => typeof v === "string" && v !== "" ? v : void 0;
|
|
182
|
+
const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
183
|
+
const documented = str(p.error) ?? str(p.code) ?? fallback?.code;
|
|
184
|
+
const sub = str(p.detail_code) ?? str(p.detailCode) ?? str(p.code);
|
|
185
|
+
const code = documented ?? "stream_failed";
|
|
186
|
+
const detailCode = sub && sub !== code ? sub : void 0;
|
|
187
|
+
const message = str(p.message) ?? (payload instanceof Error ? payload.message : void 0) ?? fallback?.message ?? code;
|
|
188
|
+
return new AIError({
|
|
189
|
+
code,
|
|
190
|
+
message,
|
|
191
|
+
retryable: typeof p.retryable === "boolean" ? p.retryable : void 0,
|
|
192
|
+
status: num(p.status) ?? num(p.statusCode) ?? fallback?.status,
|
|
193
|
+
provider: str(p.provider),
|
|
194
|
+
model: str(p.model),
|
|
195
|
+
retryAfter: num(p.retry_after_seconds) ?? num(p.retryAfter),
|
|
196
|
+
detailCode,
|
|
197
|
+
sessionId: str(p.session_id) ?? str(p.sessionId) ?? fallback?.sessionId
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
var AuthError = class extends Error {
|
|
201
|
+
constructor(message) {
|
|
202
|
+
super(message);
|
|
203
|
+
this.name = "AuthError";
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
var GameError = class extends Error {
|
|
207
|
+
constructor(init) {
|
|
208
|
+
super(init.message || init.code || "GameError");
|
|
209
|
+
this.name = "GameError";
|
|
210
|
+
this.code = init.code || "UNKNOWN";
|
|
211
|
+
this.phase = init.phase;
|
|
212
|
+
this.feature = init.feature;
|
|
213
|
+
this.roomId = init.roomId;
|
|
214
|
+
this.scriptId = init.scriptId;
|
|
215
|
+
this.originClientId = init.originClientId;
|
|
216
|
+
this.requested = init.requested;
|
|
217
|
+
this.available = init.available;
|
|
218
|
+
}
|
|
219
|
+
/** `JSON.stringify(err)` 가 `{}` 가 되지 않도록 한다 (ApiError.toJSON 참조). */
|
|
220
|
+
toJSON() {
|
|
221
|
+
return {
|
|
222
|
+
name: this.name,
|
|
223
|
+
code: this.code,
|
|
224
|
+
message: this.message,
|
|
225
|
+
phase: this.phase,
|
|
226
|
+
feature: this.feature,
|
|
227
|
+
roomId: this.roomId,
|
|
228
|
+
scriptId: this.scriptId,
|
|
229
|
+
originClientId: this.originClientId,
|
|
230
|
+
requested: this.requested,
|
|
231
|
+
available: this.available
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
|
|
119
236
|
// src/api/ai.ts
|
|
120
237
|
var AIAPI = class {
|
|
121
238
|
constructor(http) {
|
|
@@ -180,13 +297,24 @@ var AIAPI = class {
|
|
|
180
297
|
signal
|
|
181
298
|
});
|
|
182
299
|
if (!response.ok) {
|
|
183
|
-
const errorData = await response.json().catch(() => ({ error: "
|
|
184
|
-
callbacks.onError?.(
|
|
300
|
+
const errorData = await response.json().catch(() => ({ error: "stream_failed" }));
|
|
301
|
+
callbacks.onError?.(
|
|
302
|
+
toAIError(errorData, {
|
|
303
|
+
message: "Stream request failed",
|
|
304
|
+
status: response.status
|
|
305
|
+
})
|
|
306
|
+
);
|
|
185
307
|
return;
|
|
186
308
|
}
|
|
187
309
|
reader = response.body?.getReader();
|
|
188
310
|
if (!reader) {
|
|
189
|
-
callbacks.onError?.(
|
|
311
|
+
callbacks.onError?.(
|
|
312
|
+
new AIError({
|
|
313
|
+
code: "stream_failed",
|
|
314
|
+
message: "ReadableStream not supported",
|
|
315
|
+
retryable: false
|
|
316
|
+
})
|
|
317
|
+
);
|
|
190
318
|
return;
|
|
191
319
|
}
|
|
192
320
|
const decoder = new TextDecoder();
|
|
@@ -207,9 +335,7 @@ var AIAPI = class {
|
|
|
207
335
|
try {
|
|
208
336
|
const event = JSON.parse(data);
|
|
209
337
|
if (event.error) {
|
|
210
|
-
callbacks.onError?.(
|
|
211
|
-
event.message || event.error || "stream error"
|
|
212
|
-
);
|
|
338
|
+
callbacks.onError?.(toAIError(event));
|
|
213
339
|
return;
|
|
214
340
|
}
|
|
215
341
|
if (event.type === "sources" && event.sources) {
|
|
@@ -1194,37 +1320,6 @@ var AnalyticsAPI = class {
|
|
|
1194
1320
|
}
|
|
1195
1321
|
};
|
|
1196
1322
|
|
|
1197
|
-
// src/types/error.ts
|
|
1198
|
-
var ApiError = class extends Error {
|
|
1199
|
-
constructor(statusCode, message, code, details) {
|
|
1200
|
-
super(message);
|
|
1201
|
-
this.statusCode = statusCode;
|
|
1202
|
-
this.name = "ApiError";
|
|
1203
|
-
this.code = code;
|
|
1204
|
-
this.details = details;
|
|
1205
|
-
}
|
|
1206
|
-
};
|
|
1207
|
-
var AuthError = class extends Error {
|
|
1208
|
-
constructor(message) {
|
|
1209
|
-
super(message);
|
|
1210
|
-
this.name = "AuthError";
|
|
1211
|
-
}
|
|
1212
|
-
};
|
|
1213
|
-
var GameError = class extends Error {
|
|
1214
|
-
constructor(init) {
|
|
1215
|
-
super(init.message || init.code || "GameError");
|
|
1216
|
-
this.name = "GameError";
|
|
1217
|
-
this.code = init.code || "UNKNOWN";
|
|
1218
|
-
this.phase = init.phase;
|
|
1219
|
-
this.feature = init.feature;
|
|
1220
|
-
this.roomId = init.roomId;
|
|
1221
|
-
this.scriptId = init.scriptId;
|
|
1222
|
-
this.originClientId = init.originClientId;
|
|
1223
|
-
this.requested = init.requested;
|
|
1224
|
-
this.available = init.available;
|
|
1225
|
-
}
|
|
1226
|
-
};
|
|
1227
|
-
|
|
1228
1323
|
// src/core/validate.ts
|
|
1229
1324
|
function checkType(value, type) {
|
|
1230
1325
|
switch (type) {
|
|
@@ -6748,9 +6843,16 @@ var RealtimeAPI = class {
|
|
|
6748
6843
|
});
|
|
6749
6844
|
this.pendingRequests.clear();
|
|
6750
6845
|
this.subscriptions.clear();
|
|
6751
|
-
this.streamSessions.forEach((session) => {
|
|
6846
|
+
this.streamSessions.forEach((session, sessionId) => {
|
|
6752
6847
|
if (session.handlers.onError) {
|
|
6753
|
-
session.handlers.onError(
|
|
6848
|
+
session.handlers.onError(
|
|
6849
|
+
new AIError({
|
|
6850
|
+
code: "service_unavailable",
|
|
6851
|
+
message: "\uC2E4\uC2DC\uAC04 \uC5F0\uACB0\uC774 \uC885\uB8CC\uB418\uC5B4 AI \uC2A4\uD2B8\uB9AC\uBC0D\uC774 \uC911\uB2E8\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC7AC\uC5F0\uACB0 \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694.",
|
|
6852
|
+
retryable: true,
|
|
6853
|
+
sessionId
|
|
6854
|
+
})
|
|
6855
|
+
);
|
|
6754
6856
|
}
|
|
6755
6857
|
});
|
|
6756
6858
|
this.streamSessions.clear();
|
|
@@ -7015,17 +7117,26 @@ var RealtimeAPI = class {
|
|
|
7015
7117
|
signal
|
|
7016
7118
|
});
|
|
7017
7119
|
if (!response.ok) {
|
|
7018
|
-
const errData = await response.json().catch(() => ({ error: "
|
|
7120
|
+
const errData = await response.json().catch(() => ({ error: "stream_failed" }));
|
|
7019
7121
|
handlers.onError?.(
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7122
|
+
toAIError(errData, {
|
|
7123
|
+
message: "Stream request failed",
|
|
7124
|
+
sessionId,
|
|
7125
|
+
status: response.status
|
|
7126
|
+
})
|
|
7023
7127
|
);
|
|
7024
7128
|
return;
|
|
7025
7129
|
}
|
|
7026
7130
|
reader = response.body?.getReader();
|
|
7027
7131
|
if (!reader) {
|
|
7028
|
-
handlers.onError?.(
|
|
7132
|
+
handlers.onError?.(
|
|
7133
|
+
new AIError({
|
|
7134
|
+
code: "stream_failed",
|
|
7135
|
+
message: "ReadableStream not supported",
|
|
7136
|
+
retryable: false,
|
|
7137
|
+
sessionId
|
|
7138
|
+
})
|
|
7139
|
+
);
|
|
7029
7140
|
return;
|
|
7030
7141
|
}
|
|
7031
7142
|
const decoder = new TextDecoder();
|
|
@@ -7052,9 +7163,7 @@ var RealtimeAPI = class {
|
|
|
7052
7163
|
try {
|
|
7053
7164
|
const ev = JSON.parse(data);
|
|
7054
7165
|
if (ev.error) {
|
|
7055
|
-
handlers.onError?.(
|
|
7056
|
-
new Error(ev.message || ev.error || "stream error")
|
|
7057
|
-
);
|
|
7166
|
+
handlers.onError?.(toAIError(ev, { sessionId }));
|
|
7058
7167
|
return;
|
|
7059
7168
|
}
|
|
7060
7169
|
if (ev.type === "tool_start") {
|
|
@@ -7098,7 +7207,14 @@ var RealtimeAPI = class {
|
|
|
7098
7207
|
} catch (err) {
|
|
7099
7208
|
const aborted = signal.aborted || err instanceof DOMException && err.name === "AbortError" || typeof err === "object" && err !== null && err.name === "AbortError";
|
|
7100
7209
|
if (!aborted) {
|
|
7101
|
-
handlers.onError?.(
|
|
7210
|
+
handlers.onError?.(
|
|
7211
|
+
new AIError({
|
|
7212
|
+
code: "service_unavailable",
|
|
7213
|
+
message: err instanceof Error ? err.message : String(err) || "AI \uC2A4\uD2B8\uB9AC\uBC0D \uC694\uCCAD\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4",
|
|
7214
|
+
retryable: true,
|
|
7215
|
+
sessionId
|
|
7216
|
+
})
|
|
7217
|
+
);
|
|
7102
7218
|
}
|
|
7103
7219
|
} finally {
|
|
7104
7220
|
this.sseSessions.delete(sessionId);
|
|
@@ -7736,12 +7852,11 @@ var RealtimeAPI = class {
|
|
|
7736
7852
|
break;
|
|
7737
7853
|
}
|
|
7738
7854
|
case "stream_error": {
|
|
7739
|
-
const data = msg.data;
|
|
7740
7855
|
if (msg.request_id) {
|
|
7741
7856
|
for (const [sessionId, session] of this.streamSessions) {
|
|
7742
7857
|
if (session.requestId === msg.request_id) {
|
|
7743
7858
|
if (session.handlers.onError) {
|
|
7744
|
-
session.handlers.onError(
|
|
7859
|
+
session.handlers.onError(toAIError(msg.data, { sessionId }));
|
|
7745
7860
|
}
|
|
7746
7861
|
this.streamSessions.delete(sessionId);
|
|
7747
7862
|
break;
|
|
@@ -7814,9 +7929,16 @@ var RealtimeAPI = class {
|
|
|
7814
7929
|
}
|
|
7815
7930
|
this.ws = null;
|
|
7816
7931
|
this._connectionId = null;
|
|
7817
|
-
this.streamSessions.forEach((session) => {
|
|
7932
|
+
this.streamSessions.forEach((session, sessionId) => {
|
|
7818
7933
|
if (session.handlers.onError) {
|
|
7819
|
-
session.handlers.onError(
|
|
7934
|
+
session.handlers.onError(
|
|
7935
|
+
new AIError({
|
|
7936
|
+
code: "service_unavailable",
|
|
7937
|
+
message: "\uC2E4\uC2DC\uAC04 \uC5F0\uACB0\uC774 \uB04A\uACA8 AI \uC2A4\uD2B8\uB9AC\uBC0D\uC774 \uC911\uB2E8\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC7AC\uC5F0\uACB0 \uD6C4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574 \uC8FC\uC138\uC694.",
|
|
7938
|
+
retryable: true,
|
|
7939
|
+
sessionId
|
|
7940
|
+
})
|
|
7941
|
+
);
|
|
7820
7942
|
}
|
|
7821
7943
|
});
|
|
7822
7944
|
this.streamSessions.clear();
|
|
@@ -11273,13 +11395,26 @@ var HttpClient = class {
|
|
|
11273
11395
|
this.emitError(err2);
|
|
11274
11396
|
throw err2;
|
|
11275
11397
|
}
|
|
11276
|
-
const
|
|
11277
|
-
const
|
|
11398
|
+
const flatMessage = typeof errorData.message === "string" && errorData.message !== "" ? errorData.message : void 0;
|
|
11399
|
+
const explicitCode = typeof errorData.code === "string" && errorData.code !== "" ? errorData.code : void 0;
|
|
11400
|
+
const errorIsCode = typeof rawError === "string" && /^[a-z][a-z0-9_]*$/.test(rawError);
|
|
11401
|
+
const message = flatMessage ?? (typeof rawError === "string" && rawError !== "" ? rawError : "Unknown error");
|
|
11402
|
+
const code = explicitCode ?? (errorIsCode ? rawError : void 0);
|
|
11403
|
+
const legacyDetails = {};
|
|
11404
|
+
if (retryAfterSeconds !== void 0) {
|
|
11405
|
+
legacyDetails.retry_after_seconds = retryAfterSeconds;
|
|
11406
|
+
}
|
|
11407
|
+
if (typeof errorData.provider === "string") {
|
|
11408
|
+
legacyDetails.provider = errorData.provider;
|
|
11409
|
+
}
|
|
11410
|
+
if (typeof errorData.model === "string") {
|
|
11411
|
+
legacyDetails.model = errorData.model;
|
|
11412
|
+
}
|
|
11278
11413
|
const err = new ApiError(
|
|
11279
11414
|
response.status,
|
|
11280
11415
|
message,
|
|
11281
|
-
|
|
11282
|
-
legacyDetails
|
|
11416
|
+
code,
|
|
11417
|
+
Object.keys(legacyDetails).length > 0 ? legacyDetails : void 0
|
|
11283
11418
|
);
|
|
11284
11419
|
this.emitError(err);
|
|
11285
11420
|
throw err;
|
|
@@ -12257,6 +12392,7 @@ var ConnectBase = class {
|
|
|
12257
12392
|
var index_default = ConnectBase;
|
|
12258
12393
|
export {
|
|
12259
12394
|
AIAPI,
|
|
12395
|
+
AIError,
|
|
12260
12396
|
AUTH_MEMBER_ID_TOKEN,
|
|
12261
12397
|
AdsAPI,
|
|
12262
12398
|
ApiError,
|
|
@@ -12276,5 +12412,6 @@ export {
|
|
|
12276
12412
|
detectInAppBrowser,
|
|
12277
12413
|
escapeToExternalBrowser,
|
|
12278
12414
|
isWebTransportSupported,
|
|
12415
|
+
toAIError,
|
|
12279
12416
|
toCreateRoomWire
|
|
12280
12417
|
};
|