@mappa-ai/mappa-node 1.2.2 → 1.2.3
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 +169 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +64 -1
- package/dist/index.d.mts +64 -1
- package/dist/index.mjs +168 -49
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -119,6 +119,44 @@ declare class JobCanceledError extends MappaError {
|
|
|
119
119
|
});
|
|
120
120
|
toString(): string;
|
|
121
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Error thrown when SSE streaming fails after all retries.
|
|
124
|
+
*
|
|
125
|
+
* Includes recovery metadata to allow callers to resume or retry:
|
|
126
|
+
* - `jobId`: The job being streamed (when known)
|
|
127
|
+
* - `lastEventId`: Last successfully received event ID for resumption
|
|
128
|
+
* - `url`: The stream URL that failed
|
|
129
|
+
* - `retryCount`: Number of retries attempted
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* try {
|
|
134
|
+
* for await (const event of mappa.jobs.stream(jobId)) { ... }
|
|
135
|
+
* } catch (err) {
|
|
136
|
+
* if (err instanceof StreamError) {
|
|
137
|
+
* console.log(`Stream failed for job ${err.jobId}`);
|
|
138
|
+
* console.log(`Last event ID: ${err.lastEventId}`);
|
|
139
|
+
* // Can retry with: mappa.jobs.stream(err.jobId)
|
|
140
|
+
* }
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
declare class StreamError extends MappaError {
|
|
145
|
+
name: string;
|
|
146
|
+
jobId?: string;
|
|
147
|
+
lastEventId?: string;
|
|
148
|
+
url?: string;
|
|
149
|
+
retryCount: number;
|
|
150
|
+
constructor(message: string, opts: {
|
|
151
|
+
jobId?: string;
|
|
152
|
+
lastEventId?: string;
|
|
153
|
+
url?: string;
|
|
154
|
+
retryCount: number;
|
|
155
|
+
requestId?: string;
|
|
156
|
+
cause?: unknown;
|
|
157
|
+
});
|
|
158
|
+
toString(): string;
|
|
159
|
+
}
|
|
122
160
|
//#endregion
|
|
123
161
|
//#region src/resources/transport.d.ts
|
|
124
162
|
/**
|
|
@@ -152,6 +190,8 @@ type Telemetry = {
|
|
|
152
190
|
url: string;
|
|
153
191
|
requestId?: string;
|
|
154
192
|
error: unknown;
|
|
193
|
+
/** Additional context for SSE streaming errors. */
|
|
194
|
+
context?: Record<string, unknown>;
|
|
155
195
|
}) => void;
|
|
156
196
|
};
|
|
157
197
|
type TransportOptions = {
|
|
@@ -190,6 +230,9 @@ declare class Transport {
|
|
|
190
230
|
*
|
|
191
231
|
* Uses native `fetch` with streaming response body (not browser-only `EventSource`).
|
|
192
232
|
* Parses SSE format manually from the `ReadableStream`.
|
|
233
|
+
*
|
|
234
|
+
* Automatically retries on network failures (socket errors, DNS failures, etc.)
|
|
235
|
+
* up to `maxRetries` times with exponential backoff.
|
|
193
236
|
*/
|
|
194
237
|
streamSSE<T>(path: string, opts?: SSEStreamOptions): AsyncGenerator<SSEEvent<T>>;
|
|
195
238
|
/**
|
|
@@ -1373,6 +1416,26 @@ declare function isMappaError(err: unknown): err is MappaError;
|
|
|
1373
1416
|
* ```
|
|
1374
1417
|
*/
|
|
1375
1418
|
declare function isInsufficientCreditsError(err: unknown): err is InsufficientCreditsError;
|
|
1419
|
+
/**
|
|
1420
|
+
* Type guard for stream connection errors.
|
|
1421
|
+
*
|
|
1422
|
+
* Use this to detect streaming failures and access recovery metadata
|
|
1423
|
+
* like `jobId`, `lastEventId`, and `retryCount`.
|
|
1424
|
+
*
|
|
1425
|
+
* @example
|
|
1426
|
+
* ```typescript
|
|
1427
|
+
* try {
|
|
1428
|
+
* await mappa.reports.generate({ ... });
|
|
1429
|
+
* } catch (err) {
|
|
1430
|
+
* if (isStreamError(err)) {
|
|
1431
|
+
* console.log(`Stream failed for job ${err.jobId}`);
|
|
1432
|
+
* console.log(`Last event ID: ${err.lastEventId}`);
|
|
1433
|
+
* console.log(`Retries attempted: ${err.retryCount}`);
|
|
1434
|
+
* }
|
|
1435
|
+
* }
|
|
1436
|
+
* ```
|
|
1437
|
+
*/
|
|
1438
|
+
declare function isStreamError(err: unknown): err is StreamError;
|
|
1376
1439
|
//#endregion
|
|
1377
|
-
export { ApiError, AuthError, CreditBalance, CreditTransaction, CreditTransactionType, CreditUsage, CursorPage, CursorPaginationParams, Entity, EntityTagsResult, FeedbackReceipt, FileDeleteReceipt, InsufficientCreditsError, Job, JobCanceledError, JobCreditReservation, JobEvent, JobFailedError, JobStage, JobStatus, JsonReport, JsonValue, ListEntitiesOptions, ListEntitiesResponse, Mappa, MappaError, MarkdownReport, MediaFile, MediaIdRef, MediaObject, MediaProcessingStatus, MediaRef, MediaRetention, OffsetPage, OffsetPaginationParams, PdfReport, RateLimitError, Report, ReportBase, ReportCreateJobRequest, ReportForOutputType, ReportJobReceipt, ReportOutput, ReportOutputFor, ReportOutputType, ReportRunHandle, ReportTemplateId, ReportTemplateParamsMap, RetentionLockResult, Subject, TargetDominant, TargetEntityId, TargetFor, TargetMagicHint, TargetOnMiss, TargetSelector, TargetStrategy, TargetStrategyMap, TargetTimeRange, TargetTimeRangeStrategy, UrlReport, Usage, ValidationError, WaitOptions, WebhookConfig, hasEntity, isInsufficientCreditsError, isJsonReport, isMappaError, isMarkdownReport, isPdfReport, isUrlReport };
|
|
1440
|
+
export { ApiError, AuthError, CreditBalance, CreditTransaction, CreditTransactionType, CreditUsage, CursorPage, CursorPaginationParams, Entity, EntityTagsResult, FeedbackReceipt, FileDeleteReceipt, InsufficientCreditsError, Job, JobCanceledError, JobCreditReservation, JobEvent, JobFailedError, JobStage, JobStatus, JsonReport, JsonValue, ListEntitiesOptions, ListEntitiesResponse, Mappa, MappaError, MarkdownReport, MediaFile, MediaIdRef, MediaObject, MediaProcessingStatus, MediaRef, MediaRetention, OffsetPage, OffsetPaginationParams, PdfReport, RateLimitError, Report, ReportBase, ReportCreateJobRequest, ReportForOutputType, ReportJobReceipt, ReportOutput, ReportOutputFor, ReportOutputType, ReportRunHandle, ReportTemplateId, ReportTemplateParamsMap, RetentionLockResult, StreamError, Subject, TargetDominant, TargetEntityId, TargetFor, TargetMagicHint, TargetOnMiss, TargetSelector, TargetStrategy, TargetStrategyMap, TargetTimeRange, TargetTimeRangeStrategy, UrlReport, Usage, ValidationError, WaitOptions, WebhookConfig, hasEntity, isInsufficientCreditsError, isJsonReport, isMappaError, isMarkdownReport, isPdfReport, isStreamError, isUrlReport };
|
|
1378
1441
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -119,6 +119,44 @@ declare class JobCanceledError extends MappaError {
|
|
|
119
119
|
});
|
|
120
120
|
toString(): string;
|
|
121
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Error thrown when SSE streaming fails after all retries.
|
|
124
|
+
*
|
|
125
|
+
* Includes recovery metadata to allow callers to resume or retry:
|
|
126
|
+
* - `jobId`: The job being streamed (when known)
|
|
127
|
+
* - `lastEventId`: Last successfully received event ID for resumption
|
|
128
|
+
* - `url`: The stream URL that failed
|
|
129
|
+
* - `retryCount`: Number of retries attempted
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* try {
|
|
134
|
+
* for await (const event of mappa.jobs.stream(jobId)) { ... }
|
|
135
|
+
* } catch (err) {
|
|
136
|
+
* if (err instanceof StreamError) {
|
|
137
|
+
* console.log(`Stream failed for job ${err.jobId}`);
|
|
138
|
+
* console.log(`Last event ID: ${err.lastEventId}`);
|
|
139
|
+
* // Can retry with: mappa.jobs.stream(err.jobId)
|
|
140
|
+
* }
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
declare class StreamError extends MappaError {
|
|
145
|
+
name: string;
|
|
146
|
+
jobId?: string;
|
|
147
|
+
lastEventId?: string;
|
|
148
|
+
url?: string;
|
|
149
|
+
retryCount: number;
|
|
150
|
+
constructor(message: string, opts: {
|
|
151
|
+
jobId?: string;
|
|
152
|
+
lastEventId?: string;
|
|
153
|
+
url?: string;
|
|
154
|
+
retryCount: number;
|
|
155
|
+
requestId?: string;
|
|
156
|
+
cause?: unknown;
|
|
157
|
+
});
|
|
158
|
+
toString(): string;
|
|
159
|
+
}
|
|
122
160
|
//#endregion
|
|
123
161
|
//#region src/resources/transport.d.ts
|
|
124
162
|
/**
|
|
@@ -152,6 +190,8 @@ type Telemetry = {
|
|
|
152
190
|
url: string;
|
|
153
191
|
requestId?: string;
|
|
154
192
|
error: unknown;
|
|
193
|
+
/** Additional context for SSE streaming errors. */
|
|
194
|
+
context?: Record<string, unknown>;
|
|
155
195
|
}) => void;
|
|
156
196
|
};
|
|
157
197
|
type TransportOptions = {
|
|
@@ -190,6 +230,9 @@ declare class Transport {
|
|
|
190
230
|
*
|
|
191
231
|
* Uses native `fetch` with streaming response body (not browser-only `EventSource`).
|
|
192
232
|
* Parses SSE format manually from the `ReadableStream`.
|
|
233
|
+
*
|
|
234
|
+
* Automatically retries on network failures (socket errors, DNS failures, etc.)
|
|
235
|
+
* up to `maxRetries` times with exponential backoff.
|
|
193
236
|
*/
|
|
194
237
|
streamSSE<T>(path: string, opts?: SSEStreamOptions): AsyncGenerator<SSEEvent<T>>;
|
|
195
238
|
/**
|
|
@@ -1373,6 +1416,26 @@ declare function isMappaError(err: unknown): err is MappaError;
|
|
|
1373
1416
|
* ```
|
|
1374
1417
|
*/
|
|
1375
1418
|
declare function isInsufficientCreditsError(err: unknown): err is InsufficientCreditsError;
|
|
1419
|
+
/**
|
|
1420
|
+
* Type guard for stream connection errors.
|
|
1421
|
+
*
|
|
1422
|
+
* Use this to detect streaming failures and access recovery metadata
|
|
1423
|
+
* like `jobId`, `lastEventId`, and `retryCount`.
|
|
1424
|
+
*
|
|
1425
|
+
* @example
|
|
1426
|
+
* ```typescript
|
|
1427
|
+
* try {
|
|
1428
|
+
* await mappa.reports.generate({ ... });
|
|
1429
|
+
* } catch (err) {
|
|
1430
|
+
* if (isStreamError(err)) {
|
|
1431
|
+
* console.log(`Stream failed for job ${err.jobId}`);
|
|
1432
|
+
* console.log(`Last event ID: ${err.lastEventId}`);
|
|
1433
|
+
* console.log(`Retries attempted: ${err.retryCount}`);
|
|
1434
|
+
* }
|
|
1435
|
+
* }
|
|
1436
|
+
* ```
|
|
1437
|
+
*/
|
|
1438
|
+
declare function isStreamError(err: unknown): err is StreamError;
|
|
1376
1439
|
//#endregion
|
|
1377
|
-
export { ApiError, AuthError, CreditBalance, CreditTransaction, CreditTransactionType, CreditUsage, CursorPage, CursorPaginationParams, Entity, EntityTagsResult, FeedbackReceipt, FileDeleteReceipt, InsufficientCreditsError, Job, JobCanceledError, JobCreditReservation, JobEvent, JobFailedError, JobStage, JobStatus, JsonReport, JsonValue, ListEntitiesOptions, ListEntitiesResponse, Mappa, MappaError, MarkdownReport, MediaFile, MediaIdRef, MediaObject, MediaProcessingStatus, MediaRef, MediaRetention, OffsetPage, OffsetPaginationParams, PdfReport, RateLimitError, Report, ReportBase, ReportCreateJobRequest, ReportForOutputType, ReportJobReceipt, ReportOutput, ReportOutputFor, ReportOutputType, ReportRunHandle, ReportTemplateId, ReportTemplateParamsMap, RetentionLockResult, Subject, TargetDominant, TargetEntityId, TargetFor, TargetMagicHint, TargetOnMiss, TargetSelector, TargetStrategy, TargetStrategyMap, TargetTimeRange, TargetTimeRangeStrategy, UrlReport, Usage, ValidationError, WaitOptions, WebhookConfig, hasEntity, isInsufficientCreditsError, isJsonReport, isMappaError, isMarkdownReport, isPdfReport, isUrlReport };
|
|
1440
|
+
export { ApiError, AuthError, CreditBalance, CreditTransaction, CreditTransactionType, CreditUsage, CursorPage, CursorPaginationParams, Entity, EntityTagsResult, FeedbackReceipt, FileDeleteReceipt, InsufficientCreditsError, Job, JobCanceledError, JobCreditReservation, JobEvent, JobFailedError, JobStage, JobStatus, JsonReport, JsonValue, ListEntitiesOptions, ListEntitiesResponse, Mappa, MappaError, MarkdownReport, MediaFile, MediaIdRef, MediaObject, MediaProcessingStatus, MediaRef, MediaRetention, OffsetPage, OffsetPaginationParams, PdfReport, RateLimitError, Report, ReportBase, ReportCreateJobRequest, ReportForOutputType, ReportJobReceipt, ReportOutput, ReportOutputFor, ReportOutputType, ReportRunHandle, ReportTemplateId, ReportTemplateParamsMap, RetentionLockResult, StreamError, Subject, TargetDominant, TargetEntityId, TargetFor, TargetMagicHint, TargetOnMiss, TargetSelector, TargetStrategy, TargetStrategyMap, TargetTimeRange, TargetTimeRangeStrategy, UrlReport, Usage, ValidationError, WaitOptions, WebhookConfig, hasEntity, isInsufficientCreditsError, isJsonReport, isMappaError, isMarkdownReport, isPdfReport, isStreamError, isUrlReport };
|
|
1378
1441
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -170,6 +170,54 @@ var JobCanceledError = class extends MappaError {
|
|
|
170
170
|
return lines.join("\n");
|
|
171
171
|
}
|
|
172
172
|
};
|
|
173
|
+
/**
|
|
174
|
+
* Error thrown when SSE streaming fails after all retries.
|
|
175
|
+
*
|
|
176
|
+
* Includes recovery metadata to allow callers to resume or retry:
|
|
177
|
+
* - `jobId`: The job being streamed (when known)
|
|
178
|
+
* - `lastEventId`: Last successfully received event ID for resumption
|
|
179
|
+
* - `url`: The stream URL that failed
|
|
180
|
+
* - `retryCount`: Number of retries attempted
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* try {
|
|
185
|
+
* for await (const event of mappa.jobs.stream(jobId)) { ... }
|
|
186
|
+
* } catch (err) {
|
|
187
|
+
* if (err instanceof StreamError) {
|
|
188
|
+
* console.log(`Stream failed for job ${err.jobId}`);
|
|
189
|
+
* console.log(`Last event ID: ${err.lastEventId}`);
|
|
190
|
+
* // Can retry with: mappa.jobs.stream(err.jobId)
|
|
191
|
+
* }
|
|
192
|
+
* }
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
var StreamError = class extends MappaError {
|
|
196
|
+
name = "StreamError";
|
|
197
|
+
jobId;
|
|
198
|
+
lastEventId;
|
|
199
|
+
url;
|
|
200
|
+
retryCount;
|
|
201
|
+
constructor(message, opts) {
|
|
202
|
+
super(message, {
|
|
203
|
+
requestId: opts.requestId,
|
|
204
|
+
cause: opts.cause
|
|
205
|
+
});
|
|
206
|
+
this.jobId = opts.jobId;
|
|
207
|
+
this.lastEventId = opts.lastEventId;
|
|
208
|
+
this.url = opts.url;
|
|
209
|
+
this.retryCount = opts.retryCount;
|
|
210
|
+
}
|
|
211
|
+
toString() {
|
|
212
|
+
const lines = [`${this.name}: ${this.message}`];
|
|
213
|
+
if (this.jobId) lines.push(` Job ID: ${this.jobId}`);
|
|
214
|
+
if (this.lastEventId) lines.push(` Last Event ID: ${this.lastEventId}`);
|
|
215
|
+
if (this.url) lines.push(` URL: ${this.url}`);
|
|
216
|
+
lines.push(` Retry Count: ${this.retryCount}`);
|
|
217
|
+
if (this.requestId) lines.push(` Request ID: ${this.requestId}`);
|
|
218
|
+
return lines.join("\n");
|
|
219
|
+
}
|
|
220
|
+
};
|
|
173
221
|
|
|
174
222
|
//#endregion
|
|
175
223
|
//#region src/resources/credits.ts
|
|
@@ -885,10 +933,19 @@ var JobsResource = class {
|
|
|
885
933
|
} catch (error) {
|
|
886
934
|
if (opts?.signal?.aborted) throw error;
|
|
887
935
|
retries++;
|
|
888
|
-
if (retries >= maxRetries) throw
|
|
936
|
+
if (retries >= maxRetries) throw new StreamError(`Stream connection failed for job ${jobId} after ${maxRetries} retries`, {
|
|
937
|
+
jobId,
|
|
938
|
+
lastEventId,
|
|
939
|
+
retryCount: retries,
|
|
940
|
+
cause: error
|
|
941
|
+
});
|
|
889
942
|
await this.backoff(retries);
|
|
890
943
|
}
|
|
891
|
-
throw new
|
|
944
|
+
throw new StreamError(`Failed to get status for job ${jobId} after ${maxRetries} retries`, {
|
|
945
|
+
jobId,
|
|
946
|
+
lastEventId,
|
|
947
|
+
retryCount: maxRetries
|
|
948
|
+
});
|
|
892
949
|
}
|
|
893
950
|
/**
|
|
894
951
|
* Map an SSE event to a JobEvent.
|
|
@@ -1270,6 +1327,25 @@ function shouldRetry(opts, err) {
|
|
|
1270
1327
|
if (err instanceof TypeError) return { retry: true };
|
|
1271
1328
|
return { retry: false };
|
|
1272
1329
|
}
|
|
1330
|
+
/**
|
|
1331
|
+
* Checks if an error is a network-level failure that's safe to retry.
|
|
1332
|
+
* Includes socket failures, DNS errors, and fetch TypeErrors.
|
|
1333
|
+
*/
|
|
1334
|
+
function isNetworkError(err) {
|
|
1335
|
+
if (err instanceof TypeError) return true;
|
|
1336
|
+
if (err && typeof err === "object") {
|
|
1337
|
+
const code = err.code;
|
|
1338
|
+
if (typeof code === "string") return [
|
|
1339
|
+
"FailedToOpenSocket",
|
|
1340
|
+
"ECONNREFUSED",
|
|
1341
|
+
"ECONNRESET",
|
|
1342
|
+
"ETIMEDOUT",
|
|
1343
|
+
"ENOTFOUND",
|
|
1344
|
+
"EAI_AGAIN"
|
|
1345
|
+
].includes(code);
|
|
1346
|
+
}
|
|
1347
|
+
return false;
|
|
1348
|
+
}
|
|
1273
1349
|
var Transport = class {
|
|
1274
1350
|
fetchImpl;
|
|
1275
1351
|
constructor(opts) {
|
|
@@ -1281,10 +1357,14 @@ var Transport = class {
|
|
|
1281
1357
|
*
|
|
1282
1358
|
* Uses native `fetch` with streaming response body (not browser-only `EventSource`).
|
|
1283
1359
|
* Parses SSE format manually from the `ReadableStream`.
|
|
1360
|
+
*
|
|
1361
|
+
* Automatically retries on network failures (socket errors, DNS failures, etc.)
|
|
1362
|
+
* up to `maxRetries` times with exponential backoff.
|
|
1284
1363
|
*/
|
|
1285
1364
|
async *streamSSE(path, opts) {
|
|
1286
1365
|
const url = buildUrl(this.opts.baseUrl, path);
|
|
1287
1366
|
const requestId = randomId("req");
|
|
1367
|
+
const maxRetries = Math.max(0, this.opts.maxRetries);
|
|
1288
1368
|
const headers = {
|
|
1289
1369
|
Accept: "text/event-stream",
|
|
1290
1370
|
"Cache-Control": "no-cache",
|
|
@@ -1294,57 +1374,74 @@ var Transport = class {
|
|
|
1294
1374
|
...this.opts.defaultHeaders ?? {}
|
|
1295
1375
|
};
|
|
1296
1376
|
if (opts?.lastEventId) headers["Last-Event-ID"] = opts.lastEventId;
|
|
1297
|
-
const controller = new AbortController();
|
|
1298
|
-
const timeout = setTimeout(() => controller.abort(makeAbortError()), this.opts.timeoutMs);
|
|
1299
|
-
if (hasAbortSignal(opts?.signal)) {
|
|
1300
|
-
const signal = opts?.signal;
|
|
1301
|
-
if (signal?.aborted) {
|
|
1302
|
-
clearTimeout(timeout);
|
|
1303
|
-
throw makeAbortError();
|
|
1304
|
-
}
|
|
1305
|
-
signal?.addEventListener("abort", () => controller.abort(makeAbortError()), { once: true });
|
|
1306
|
-
}
|
|
1307
|
-
this.opts.telemetry?.onRequest?.({
|
|
1308
|
-
method: "GET",
|
|
1309
|
-
url,
|
|
1310
|
-
requestId
|
|
1311
|
-
});
|
|
1312
1377
|
let res;
|
|
1313
|
-
|
|
1314
|
-
|
|
1378
|
+
let lastError;
|
|
1379
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
1380
|
+
const controller = new AbortController();
|
|
1381
|
+
const timeout = setTimeout(() => controller.abort(makeAbortError()), this.opts.timeoutMs);
|
|
1382
|
+
if (hasAbortSignal(opts?.signal)) {
|
|
1383
|
+
const signal = opts?.signal;
|
|
1384
|
+
if (signal?.aborted) {
|
|
1385
|
+
clearTimeout(timeout);
|
|
1386
|
+
throw makeAbortError();
|
|
1387
|
+
}
|
|
1388
|
+
signal?.addEventListener("abort", () => controller.abort(makeAbortError()), { once: true });
|
|
1389
|
+
}
|
|
1390
|
+
this.opts.telemetry?.onRequest?.({
|
|
1315
1391
|
method: "GET",
|
|
1316
|
-
headers,
|
|
1317
|
-
signal: controller.signal
|
|
1318
|
-
});
|
|
1319
|
-
} catch (err) {
|
|
1320
|
-
clearTimeout(timeout);
|
|
1321
|
-
this.opts.telemetry?.onError?.({
|
|
1322
|
-
url,
|
|
1323
|
-
requestId,
|
|
1324
|
-
error: err
|
|
1325
|
-
});
|
|
1326
|
-
throw err;
|
|
1327
|
-
}
|
|
1328
|
-
if (!res.ok) {
|
|
1329
|
-
clearTimeout(timeout);
|
|
1330
|
-
const { parsed } = await readBody(res);
|
|
1331
|
-
const apiErr = coerceApiError(res, parsed);
|
|
1332
|
-
this.opts.telemetry?.onError?.({
|
|
1333
1392
|
url,
|
|
1334
|
-
requestId
|
|
1335
|
-
error: apiErr
|
|
1393
|
+
requestId
|
|
1336
1394
|
});
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1395
|
+
try {
|
|
1396
|
+
res = await this.fetchImpl(url, {
|
|
1397
|
+
method: "GET",
|
|
1398
|
+
headers,
|
|
1399
|
+
signal: controller.signal
|
|
1400
|
+
});
|
|
1401
|
+
clearTimeout(timeout);
|
|
1402
|
+
if (!res.ok) {
|
|
1403
|
+
const { parsed } = await readBody(res);
|
|
1404
|
+
const apiErr = coerceApiError(res, parsed);
|
|
1405
|
+
this.opts.telemetry?.onError?.({
|
|
1406
|
+
url,
|
|
1407
|
+
requestId,
|
|
1408
|
+
error: apiErr,
|
|
1409
|
+
context: {
|
|
1410
|
+
attempt,
|
|
1411
|
+
lastEventId: opts?.lastEventId
|
|
1412
|
+
}
|
|
1413
|
+
});
|
|
1414
|
+
if (res.status >= 500 && res.status <= 599 && attempt < maxRetries) {
|
|
1415
|
+
const delay = jitter(backoffMs(attempt + 1, 500, 4e3));
|
|
1416
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
1417
|
+
continue;
|
|
1418
|
+
}
|
|
1419
|
+
throw apiErr;
|
|
1420
|
+
}
|
|
1421
|
+
break;
|
|
1422
|
+
} catch (err) {
|
|
1423
|
+
clearTimeout(timeout);
|
|
1424
|
+
lastError = err;
|
|
1425
|
+
this.opts.telemetry?.onError?.({
|
|
1426
|
+
url,
|
|
1427
|
+
requestId,
|
|
1428
|
+
error: err,
|
|
1429
|
+
context: {
|
|
1430
|
+
attempt,
|
|
1431
|
+
lastEventId: opts?.lastEventId
|
|
1432
|
+
}
|
|
1433
|
+
});
|
|
1434
|
+
if (isNetworkError(err) && attempt < maxRetries) {
|
|
1435
|
+
const delay = jitter(backoffMs(attempt + 1, 500, 4e3));
|
|
1436
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
1437
|
+
continue;
|
|
1438
|
+
}
|
|
1439
|
+
throw err;
|
|
1440
|
+
}
|
|
1347
1441
|
}
|
|
1442
|
+
if (!res) throw lastError;
|
|
1443
|
+
if (!res.body) throw new MappaError("SSE response has no body");
|
|
1444
|
+
yield* this.parseSSEStream(res.body);
|
|
1348
1445
|
}
|
|
1349
1446
|
/**
|
|
1350
1447
|
* Parse SSE events from a ReadableStream.
|
|
@@ -1711,7 +1808,29 @@ function isMappaError(err) {
|
|
|
1711
1808
|
function isInsufficientCreditsError(err) {
|
|
1712
1809
|
return err instanceof InsufficientCreditsError;
|
|
1713
1810
|
}
|
|
1811
|
+
/**
|
|
1812
|
+
* Type guard for stream connection errors.
|
|
1813
|
+
*
|
|
1814
|
+
* Use this to detect streaming failures and access recovery metadata
|
|
1815
|
+
* like `jobId`, `lastEventId`, and `retryCount`.
|
|
1816
|
+
*
|
|
1817
|
+
* @example
|
|
1818
|
+
* ```typescript
|
|
1819
|
+
* try {
|
|
1820
|
+
* await mappa.reports.generate({ ... });
|
|
1821
|
+
* } catch (err) {
|
|
1822
|
+
* if (isStreamError(err)) {
|
|
1823
|
+
* console.log(`Stream failed for job ${err.jobId}`);
|
|
1824
|
+
* console.log(`Last event ID: ${err.lastEventId}`);
|
|
1825
|
+
* console.log(`Retries attempted: ${err.retryCount}`);
|
|
1826
|
+
* }
|
|
1827
|
+
* }
|
|
1828
|
+
* ```
|
|
1829
|
+
*/
|
|
1830
|
+
function isStreamError(err) {
|
|
1831
|
+
return err instanceof StreamError;
|
|
1832
|
+
}
|
|
1714
1833
|
|
|
1715
1834
|
//#endregion
|
|
1716
|
-
export { ApiError, AuthError, InsufficientCreditsError, JobCanceledError, JobFailedError, Mappa, MappaError, RateLimitError, ValidationError, hasEntity, isInsufficientCreditsError, isJsonReport, isMappaError, isMarkdownReport, isPdfReport, isUrlReport };
|
|
1835
|
+
export { ApiError, AuthError, InsufficientCreditsError, JobCanceledError, JobFailedError, Mappa, MappaError, RateLimitError, StreamError, ValidationError, hasEntity, isInsufficientCreditsError, isJsonReport, isMappaError, isMarkdownReport, isPdfReport, isStreamError, isUrlReport };
|
|
1717
1836
|
//# sourceMappingURL=index.mjs.map
|