@spooled/sdk 1.3.0 → 1.4.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/README.md +81 -9
- package/dist/{index-BVWKEr6p.d.cts → index-Bqgiu-NN.d.cts} +569 -95
- package/dist/{index-BVWKEr6p.d.ts → index-Bqgiu-NN.d.ts} +569 -95
- package/dist/index.cjs +341 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -186
- package/dist/index.d.ts +3 -186
- package/dist/index.js +341 -126
- package/dist/index.js.map +1 -1
- package/dist/worker/index.cjs +1 -1
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +1 -1
- package/dist/worker/index.d.ts +1 -1
- package/dist/worker/index.js +1 -1
- package/dist/worker/index.js.map +1 -1
- package/package.json +8 -7
- package/proto/spooled.proto +19 -1
package/dist/index.js
CHANGED
|
@@ -24,10 +24,10 @@ var DEFAULT_CONFIG = {
|
|
|
24
24
|
successThreshold: 3,
|
|
25
25
|
timeout: 3e4
|
|
26
26
|
},
|
|
27
|
-
userAgent: "@spooled/sdk-nodejs/1.
|
|
27
|
+
userAgent: "@spooled/sdk-nodejs/1.4.1",
|
|
28
28
|
autoRefreshToken: true
|
|
29
29
|
};
|
|
30
|
-
var SDK_VERSION = "1.
|
|
30
|
+
var SDK_VERSION = "1.4.1";
|
|
31
31
|
var API_VERSION = "v1";
|
|
32
32
|
var API_BASE_PATH = `/api/${API_VERSION}`;
|
|
33
33
|
function normalizeCredential(value) {
|
|
@@ -340,6 +340,10 @@ function parseRateLimitHeaders(headers) {
|
|
|
340
340
|
info.reset = new Date(timestamp * 1e3);
|
|
341
341
|
}
|
|
342
342
|
}
|
|
343
|
+
const scope = headers.get("X-RateLimit-Scope");
|
|
344
|
+
if (scope) {
|
|
345
|
+
info.scope = scope.trim();
|
|
346
|
+
}
|
|
343
347
|
return info;
|
|
344
348
|
}
|
|
345
349
|
var MAX_RAW_ERROR_BODY_CHARS = 500;
|
|
@@ -619,6 +623,8 @@ var HttpClient = class {
|
|
|
619
623
|
* refresh and fail even though the token was about to be replaced.
|
|
620
624
|
*/
|
|
621
625
|
refreshInFlight = null;
|
|
626
|
+
/** Rate-limit headers of the most recent response that carried them */
|
|
627
|
+
lastRateLimit;
|
|
622
628
|
constructor(config, circuitBreaker) {
|
|
623
629
|
this.config = config;
|
|
624
630
|
this.circuitBreaker = circuitBreaker;
|
|
@@ -631,6 +637,14 @@ var HttpClient = class {
|
|
|
631
637
|
setAuthToken(token) {
|
|
632
638
|
this.authToken = token;
|
|
633
639
|
}
|
|
640
|
+
/**
|
|
641
|
+
* The `X-RateLimit-*` (and `Retry-After`) values of the most recent
|
|
642
|
+
* response that carried them, successful or not. `undefined` until such a
|
|
643
|
+
* response arrives. With concurrent requests it is the last one to finish.
|
|
644
|
+
*/
|
|
645
|
+
getLastRateLimitInfo() {
|
|
646
|
+
return this.lastRateLimit ? { ...this.lastRateLimit } : void 0;
|
|
647
|
+
}
|
|
634
648
|
/**
|
|
635
649
|
* Set the token refresh function.
|
|
636
650
|
*
|
|
@@ -777,6 +791,7 @@ var HttpClient = class {
|
|
|
777
791
|
);
|
|
778
792
|
}
|
|
779
793
|
this.debug?.(`Response: ${response.status}`, { url });
|
|
794
|
+
this.recordRateLimit(response.headers);
|
|
780
795
|
if (!response.ok) {
|
|
781
796
|
if (response.status === 401 && this.refreshTokenFn && !hasRefreshed && !options.skipAuthRefresh) {
|
|
782
797
|
const alreadyRefreshed = this.authToken !== tokenUsed;
|
|
@@ -803,6 +818,13 @@ var HttpClient = class {
|
|
|
803
818
|
data
|
|
804
819
|
};
|
|
805
820
|
}
|
|
821
|
+
/** Remember the rate-limit headers of a response that has them. */
|
|
822
|
+
recordRateLimit(headers) {
|
|
823
|
+
if (!headers || typeof headers.get !== "function" || headers.get("X-RateLimit-Limit") === null && headers.get("X-RateLimit-Remaining") === null) {
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
this.lastRateLimit = parseRateLimitHeaders(headers);
|
|
827
|
+
}
|
|
806
828
|
/**
|
|
807
829
|
* Make an HTTP request with retry and circuit breaker
|
|
808
830
|
*/
|
|
@@ -930,6 +952,12 @@ var CircuitState = /* @__PURE__ */ ((CircuitState2) => {
|
|
|
930
952
|
CircuitState2["HALF_OPEN"] = "HALF_OPEN";
|
|
931
953
|
return CircuitState2;
|
|
932
954
|
})(CircuitState || {});
|
|
955
|
+
function isCircuitBreakerFailure(error) {
|
|
956
|
+
if (error instanceof RateLimitError) {
|
|
957
|
+
return false;
|
|
958
|
+
}
|
|
959
|
+
return isRetryableError(error);
|
|
960
|
+
}
|
|
933
961
|
var CircuitBreaker = class {
|
|
934
962
|
state = "CLOSED" /* CLOSED */;
|
|
935
963
|
failureCount = 0;
|
|
@@ -990,7 +1018,7 @@ var CircuitBreaker = class {
|
|
|
990
1018
|
if (!this.config.enabled) {
|
|
991
1019
|
return;
|
|
992
1020
|
}
|
|
993
|
-
const shouldCount = this.config.isFailure ? this.config.isFailure(error) :
|
|
1021
|
+
const shouldCount = this.config.isFailure ? this.config.isFailure(error) : isCircuitBreakerFailure(error);
|
|
994
1022
|
if (!shouldCount) {
|
|
995
1023
|
return;
|
|
996
1024
|
}
|
|
@@ -1188,12 +1216,31 @@ function coerceFailureMessage(message) {
|
|
|
1188
1216
|
return codePoints.length <= MAX_FAILURE_MESSAGE_CHARS ? text : codePoints.slice(0, MAX_FAILURE_MESSAGE_CHARS).join("");
|
|
1189
1217
|
}
|
|
1190
1218
|
|
|
1219
|
+
// src/utils/paging.ts
|
|
1220
|
+
var HAS_MORE_HEADER = "X-Has-More";
|
|
1221
|
+
function hasMoreFromHeaders(headers, count, limit, defaultLimit, maxLimit) {
|
|
1222
|
+
const header = headers.get(HAS_MORE_HEADER);
|
|
1223
|
+
if (header !== null) {
|
|
1224
|
+
return header.trim().toLowerCase() === "true";
|
|
1225
|
+
}
|
|
1226
|
+
const applied = Math.min(Math.max(limit ?? defaultLimit, 1), maxLimit);
|
|
1227
|
+
return count >= applied;
|
|
1228
|
+
}
|
|
1229
|
+
function toQueryTimestamp(value) {
|
|
1230
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1191
1233
|
// src/resources/jobs.ts
|
|
1234
|
+
var JOB_LIST_DEFAULT_LIMIT = 50;
|
|
1235
|
+
var JOB_LIST_MAX_LIMIT = 100;
|
|
1236
|
+
var JOB_HISTORY_DEFAULT_LIMIT = 100;
|
|
1237
|
+
var JOB_HISTORY_MAX_LIMIT = 500;
|
|
1192
1238
|
var JobsResource = class {
|
|
1193
1239
|
constructor(http) {
|
|
1194
1240
|
this.http = http;
|
|
1195
1241
|
this.dlq = {
|
|
1196
1242
|
list: this.listDlq.bind(this),
|
|
1243
|
+
listPage: this.listDlqPage.bind(this),
|
|
1197
1244
|
retry: this.retryDlq.bind(this),
|
|
1198
1245
|
purge: this.purgeDlq.bind(this)
|
|
1199
1246
|
};
|
|
@@ -1217,15 +1264,36 @@ var JobsResource = class {
|
|
|
1217
1264
|
}
|
|
1218
1265
|
/**
|
|
1219
1266
|
* List jobs with optional filtering
|
|
1267
|
+
*
|
|
1268
|
+
* `status` takes one status or several, and `q`, `jobType`, `createdAfter`
|
|
1269
|
+
* and `createdBefore` filter on the server (API 0.1.122+). Use
|
|
1270
|
+
* {@link JobsResource.listPage} to also learn whether another page follows.
|
|
1220
1271
|
*/
|
|
1221
1272
|
async list(params) {
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1273
|
+
return (await this.listPage(params)).data;
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* List one page of jobs with `hasMore` from the `X-Has-More` header
|
|
1277
|
+
* (API 0.1.122+). Takes the same filters as {@link JobsResource.list}.
|
|
1278
|
+
*
|
|
1279
|
+
* @example
|
|
1280
|
+
* ```typescript
|
|
1281
|
+
* let offset = 0;
|
|
1282
|
+
* for (;;) {
|
|
1283
|
+
* const page = await client.jobs.listPage({
|
|
1284
|
+
* status: ["failed", "deadletter"],
|
|
1285
|
+
* createdAfter: new Date(Date.now() - 86_400_000),
|
|
1286
|
+
* limit: 100,
|
|
1287
|
+
* offset,
|
|
1288
|
+
* });
|
|
1289
|
+
* handle(page.data);
|
|
1290
|
+
* if (!page.hasMore) break;
|
|
1291
|
+
* offset += page.data.length;
|
|
1292
|
+
* }
|
|
1293
|
+
* ```
|
|
1294
|
+
*/
|
|
1295
|
+
async listPage(params) {
|
|
1296
|
+
return this.listSummaries("/jobs", params);
|
|
1229
1297
|
}
|
|
1230
1298
|
/**
|
|
1231
1299
|
* Get a job by ID
|
|
@@ -1255,6 +1323,46 @@ var JobsResource = class {
|
|
|
1255
1323
|
priority
|
|
1256
1324
|
});
|
|
1257
1325
|
}
|
|
1326
|
+
/**
|
|
1327
|
+
* Get the recorded lifecycle events of a job (`GET /jobs/{id}/history`,
|
|
1328
|
+
* API 0.1.122+), oldest first unless `order: "desc"`.
|
|
1329
|
+
*
|
|
1330
|
+
* The history is sparse: the server records REST claims (`processing`),
|
|
1331
|
+
* completions (`completed`) and failures (`retry_scheduled`,
|
|
1332
|
+
* `deadlettered`) and the scheduler's dead-letter sweeps, so a job settled
|
|
1333
|
+
* over gRPC may have few or no events. An unknown job is a `NotFoundError`.
|
|
1334
|
+
*/
|
|
1335
|
+
async history(id, params) {
|
|
1336
|
+
return (await this.historyPage(id, params)).data;
|
|
1337
|
+
}
|
|
1338
|
+
/**
|
|
1339
|
+
* One page of {@link JobsResource.history} with `hasMore` from the
|
|
1340
|
+
* `X-Has-More` header. `limit` defaults to 100 (at most 500).
|
|
1341
|
+
*/
|
|
1342
|
+
async historyPage(id, params) {
|
|
1343
|
+
const response = await this.http.request(
|
|
1344
|
+
`/jobs/${id}/history`,
|
|
1345
|
+
{
|
|
1346
|
+
method: "GET",
|
|
1347
|
+
params: {
|
|
1348
|
+
order: params?.order,
|
|
1349
|
+
limit: params?.limit,
|
|
1350
|
+
offset: params?.offset
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
);
|
|
1354
|
+
const data = response.data ?? [];
|
|
1355
|
+
return {
|
|
1356
|
+
data,
|
|
1357
|
+
hasMore: hasMoreFromHeaders(
|
|
1358
|
+
response.headers,
|
|
1359
|
+
data.length,
|
|
1360
|
+
params?.limit,
|
|
1361
|
+
JOB_HISTORY_DEFAULT_LIMIT,
|
|
1362
|
+
JOB_HISTORY_MAX_LIMIT
|
|
1363
|
+
)
|
|
1364
|
+
};
|
|
1365
|
+
}
|
|
1258
1366
|
/**
|
|
1259
1367
|
* Get job statistics
|
|
1260
1368
|
*/
|
|
@@ -1331,13 +1439,30 @@ var JobsResource = class {
|
|
|
1331
1439
|
}
|
|
1332
1440
|
// DLQ operations (private implementations)
|
|
1333
1441
|
async listDlq(params) {
|
|
1334
|
-
|
|
1335
|
-
|
|
1442
|
+
return (await this.listDlqPage(params)).data;
|
|
1443
|
+
}
|
|
1444
|
+
async listDlqPage(params) {
|
|
1445
|
+
return this.listSummaries("/jobs/dlq", params);
|
|
1446
|
+
}
|
|
1447
|
+
async listSummaries(path, params) {
|
|
1448
|
+
const response = await this.http.request(path, {
|
|
1449
|
+
method: "GET",
|
|
1450
|
+
params: jobListQuery(params)
|
|
1336
1451
|
});
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1452
|
+
const rows = response.data ?? [];
|
|
1453
|
+
return {
|
|
1454
|
+
data: rows.map((row) => ({
|
|
1455
|
+
...row,
|
|
1456
|
+
jobType: row.jobType ?? jobTypeFromPayload(row)
|
|
1457
|
+
})),
|
|
1458
|
+
hasMore: hasMoreFromHeaders(
|
|
1459
|
+
response.headers,
|
|
1460
|
+
rows.length,
|
|
1461
|
+
params?.limit,
|
|
1462
|
+
JOB_LIST_DEFAULT_LIMIT,
|
|
1463
|
+
JOB_LIST_MAX_LIMIT
|
|
1464
|
+
)
|
|
1465
|
+
};
|
|
1341
1466
|
}
|
|
1342
1467
|
async retryDlq(params) {
|
|
1343
1468
|
return this.http.post("/jobs/dlq/retry", params);
|
|
@@ -1346,6 +1471,24 @@ var JobsResource = class {
|
|
|
1346
1471
|
return this.http.post("/jobs/dlq/purge", params);
|
|
1347
1472
|
}
|
|
1348
1473
|
};
|
|
1474
|
+
function jobListQuery(params) {
|
|
1475
|
+
if (!params) {
|
|
1476
|
+
return void 0;
|
|
1477
|
+
}
|
|
1478
|
+
const { status: status2, createdAfter, createdBefore, ...rest } = params;
|
|
1479
|
+
let statusParam;
|
|
1480
|
+
if (typeof status2 === "string") {
|
|
1481
|
+
statusParam = status2;
|
|
1482
|
+
} else if (status2 && status2.length > 0) {
|
|
1483
|
+
statusParam = status2.join(",");
|
|
1484
|
+
}
|
|
1485
|
+
return {
|
|
1486
|
+
...rest,
|
|
1487
|
+
status: statusParam,
|
|
1488
|
+
createdAfter: toQueryTimestamp(createdAfter),
|
|
1489
|
+
createdBefore: toQueryTimestamp(createdBefore)
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1349
1492
|
function withJobType(job) {
|
|
1350
1493
|
return {
|
|
1351
1494
|
...job,
|
|
@@ -2169,6 +2312,31 @@ var WebhookIngestionResource = class {
|
|
|
2169
2312
|
status: raw.status
|
|
2170
2313
|
};
|
|
2171
2314
|
}
|
|
2315
|
+
/**
|
|
2316
|
+
* The inbound webhook log: accepted requests to
|
|
2317
|
+
* `POST /webhooks/{org_id}/custom`, newest first
|
|
2318
|
+
* (`GET /webhooks/deliveries`, API 0.1.122+).
|
|
2319
|
+
*
|
|
2320
|
+
* Needs an API key without a queue restriction (a queue-scoped key gets a
|
|
2321
|
+
* 403 `AuthorizationError`). Entries carry no payload and no signature;
|
|
2322
|
+
* requests that were rejected are not logged. `limit` defaults to 50 (at
|
|
2323
|
+
* most 100); an invalid filter is a 400 `ValidationError`.
|
|
2324
|
+
*/
|
|
2325
|
+
async listDeliveries(params) {
|
|
2326
|
+
const rows = await this.http.get(
|
|
2327
|
+
"/webhooks/deliveries",
|
|
2328
|
+
{
|
|
2329
|
+
params: {
|
|
2330
|
+
status: params?.status,
|
|
2331
|
+
since: toQueryTimestamp(params?.since),
|
|
2332
|
+
queueName: params?.queueName,
|
|
2333
|
+
limit: params?.limit,
|
|
2334
|
+
offset: params?.offset
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
);
|
|
2338
|
+
return rows ?? [];
|
|
2339
|
+
}
|
|
2172
2340
|
};
|
|
2173
2341
|
|
|
2174
2342
|
// src/realtime/event-map.ts
|
|
@@ -3006,6 +3174,120 @@ function clearProtoCache() {
|
|
|
3006
3174
|
function encodeFailRequest(params) {
|
|
3007
3175
|
return { ...params, retry: params.retry ?? true };
|
|
3008
3176
|
}
|
|
3177
|
+
function encodeStruct(value) {
|
|
3178
|
+
if (value == null) {
|
|
3179
|
+
return void 0;
|
|
3180
|
+
}
|
|
3181
|
+
return {
|
|
3182
|
+
fields: Object.fromEntries(
|
|
3183
|
+
Object.entries(value).map(([key, entry]) => [key, encodeValue(entry)])
|
|
3184
|
+
)
|
|
3185
|
+
};
|
|
3186
|
+
}
|
|
3187
|
+
function encodeValue(value) {
|
|
3188
|
+
if (value == null) {
|
|
3189
|
+
return { nullValue: 0 };
|
|
3190
|
+
}
|
|
3191
|
+
if (Array.isArray(value)) {
|
|
3192
|
+
return { listValue: { values: value.map(encodeValue) } };
|
|
3193
|
+
}
|
|
3194
|
+
switch (typeof value) {
|
|
3195
|
+
case "number":
|
|
3196
|
+
return { numberValue: value };
|
|
3197
|
+
case "string":
|
|
3198
|
+
return { stringValue: value };
|
|
3199
|
+
case "boolean":
|
|
3200
|
+
return { boolValue: value };
|
|
3201
|
+
case "object":
|
|
3202
|
+
return { structValue: encodeStruct(value) };
|
|
3203
|
+
default:
|
|
3204
|
+
return { stringValue: String(value) };
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
function decodeStruct(value) {
|
|
3208
|
+
if (!value || typeof value !== "object" || !("fields" in value)) {
|
|
3209
|
+
return value;
|
|
3210
|
+
}
|
|
3211
|
+
const fields = value.fields ?? {};
|
|
3212
|
+
return Object.fromEntries(
|
|
3213
|
+
Object.entries(fields).map(([key, entry]) => [key, decodeValue(entry)])
|
|
3214
|
+
);
|
|
3215
|
+
}
|
|
3216
|
+
function decodeValue(value) {
|
|
3217
|
+
if ("nullValue" in value) {
|
|
3218
|
+
return null;
|
|
3219
|
+
}
|
|
3220
|
+
if ("numberValue" in value) {
|
|
3221
|
+
return value.numberValue;
|
|
3222
|
+
}
|
|
3223
|
+
if ("stringValue" in value) {
|
|
3224
|
+
return value.stringValue;
|
|
3225
|
+
}
|
|
3226
|
+
if ("boolValue" in value) {
|
|
3227
|
+
return value.boolValue;
|
|
3228
|
+
}
|
|
3229
|
+
if ("structValue" in value) {
|
|
3230
|
+
return decodeStruct(value.structValue);
|
|
3231
|
+
}
|
|
3232
|
+
if ("listValue" in value) {
|
|
3233
|
+
return (value.listValue.values ?? []).map(decodeValue);
|
|
3234
|
+
}
|
|
3235
|
+
return void 0;
|
|
3236
|
+
}
|
|
3237
|
+
function encodeEnqueueRequest(params) {
|
|
3238
|
+
const encoded = {
|
|
3239
|
+
queueName: params.queueName,
|
|
3240
|
+
payload: encodeStruct(params.payload)
|
|
3241
|
+
};
|
|
3242
|
+
if (params.priority !== void 0) {
|
|
3243
|
+
encoded.priority = params.priority;
|
|
3244
|
+
}
|
|
3245
|
+
if (params.maxRetries !== void 0) {
|
|
3246
|
+
encoded.maxRetries = params.maxRetries;
|
|
3247
|
+
}
|
|
3248
|
+
if (params.timeoutSeconds !== void 0) {
|
|
3249
|
+
encoded.timeoutSeconds = params.timeoutSeconds;
|
|
3250
|
+
}
|
|
3251
|
+
if (params.idempotencyKey !== void 0 && params.idempotencyKey !== "") {
|
|
3252
|
+
encoded.idempotencyKey = params.idempotencyKey;
|
|
3253
|
+
}
|
|
3254
|
+
if (params.scheduledAt !== void 0) {
|
|
3255
|
+
encoded.scheduledAt = params.scheduledAt;
|
|
3256
|
+
}
|
|
3257
|
+
if (params.tags !== void 0) {
|
|
3258
|
+
encoded.tags = params.tags;
|
|
3259
|
+
}
|
|
3260
|
+
return encoded;
|
|
3261
|
+
}
|
|
3262
|
+
function encodeCompleteRequest(params) {
|
|
3263
|
+
return {
|
|
3264
|
+
...params,
|
|
3265
|
+
result: encodeStruct(params.result)
|
|
3266
|
+
};
|
|
3267
|
+
}
|
|
3268
|
+
function decodeJob(job) {
|
|
3269
|
+
return {
|
|
3270
|
+
...job,
|
|
3271
|
+
// proto-loader keeps an enum number it does not know (a status added to
|
|
3272
|
+
// the server's proto after this SDK) as a number; keep it a string so
|
|
3273
|
+
// `status` always matches its type.
|
|
3274
|
+
status: typeof job.status === "number" ? String(job.status) : job.status,
|
|
3275
|
+
payload: decodeStruct(job.payload),
|
|
3276
|
+
result: decodeStruct(job.result)
|
|
3277
|
+
};
|
|
3278
|
+
}
|
|
3279
|
+
function encodeProcessRequest(request) {
|
|
3280
|
+
if (request.fail) {
|
|
3281
|
+
return { ...request, fail: encodeFailRequest(request.fail) };
|
|
3282
|
+
}
|
|
3283
|
+
if (request.complete) {
|
|
3284
|
+
return { ...request, complete: encodeCompleteRequest(request.complete) };
|
|
3285
|
+
}
|
|
3286
|
+
return request;
|
|
3287
|
+
}
|
|
3288
|
+
function decodeProcessResponse(response) {
|
|
3289
|
+
return response.job ? { ...response, job: decodeJob(response.job) } : response;
|
|
3290
|
+
}
|
|
3009
3291
|
|
|
3010
3292
|
// src/grpc/streaming.ts
|
|
3011
3293
|
async function* asyncIterableFromStream(stream, options) {
|
|
@@ -3024,21 +3306,39 @@ async function* asyncIterableFromStream(stream, options) {
|
|
|
3024
3306
|
var AsyncIterableStream = class {
|
|
3025
3307
|
stream;
|
|
3026
3308
|
options;
|
|
3027
|
-
|
|
3309
|
+
decode;
|
|
3310
|
+
constructor(stream, options = {}, decode = (item) => item) {
|
|
3028
3311
|
this.stream = stream;
|
|
3029
3312
|
this.options = options;
|
|
3313
|
+
this.decode = decode;
|
|
3030
3314
|
}
|
|
3031
3315
|
async *[Symbol.asyncIterator]() {
|
|
3032
3316
|
const { onConnected, onError, onEnd } = this.options;
|
|
3033
3317
|
const queue = [];
|
|
3034
3318
|
let error = null;
|
|
3035
3319
|
let ended = false;
|
|
3320
|
+
let decodeFailed = false;
|
|
3036
3321
|
let resolve = null;
|
|
3037
3322
|
this.stream.on("data", (data) => {
|
|
3038
|
-
|
|
3323
|
+
if (decodeFailed) {
|
|
3324
|
+
return;
|
|
3325
|
+
}
|
|
3326
|
+
try {
|
|
3327
|
+
queue.push(this.decode(data));
|
|
3328
|
+
} catch (decodeError) {
|
|
3329
|
+
decodeFailed = true;
|
|
3330
|
+
error = decodeError instanceof Error ? decodeError : new Error(String(decodeError));
|
|
3331
|
+
try {
|
|
3332
|
+
this.stream.cancel?.();
|
|
3333
|
+
} catch {
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3039
3336
|
resolve?.();
|
|
3040
3337
|
});
|
|
3041
3338
|
this.stream.on("error", (err) => {
|
|
3339
|
+
if (decodeFailed) {
|
|
3340
|
+
return;
|
|
3341
|
+
}
|
|
3042
3342
|
error = err;
|
|
3043
3343
|
onError?.(err);
|
|
3044
3344
|
resolve?.();
|
|
@@ -3079,12 +3379,14 @@ function createProcessJobsStream(call, options) {
|
|
|
3079
3379
|
}
|
|
3080
3380
|
return {
|
|
3081
3381
|
send(request) {
|
|
3082
|
-
call.write(
|
|
3083
|
-
request.fail ? { ...request, fail: encodeFailRequest(request.fail) } : request
|
|
3084
|
-
);
|
|
3382
|
+
call.write(encodeProcessRequest(request));
|
|
3085
3383
|
},
|
|
3086
3384
|
receive() {
|
|
3087
|
-
return new AsyncIterableStream(
|
|
3385
|
+
return new AsyncIterableStream(
|
|
3386
|
+
call,
|
|
3387
|
+
{ onError, onEnd },
|
|
3388
|
+
decodeProcessResponse
|
|
3389
|
+
);
|
|
3088
3390
|
},
|
|
3089
3391
|
end() {
|
|
3090
3392
|
call.end();
|
|
@@ -3101,11 +3403,11 @@ function createJobStream(call, options) {
|
|
|
3101
3403
|
call.cancel();
|
|
3102
3404
|
});
|
|
3103
3405
|
}
|
|
3104
|
-
const iterable = new AsyncIterableStream(
|
|
3105
|
-
|
|
3106
|
-
onError,
|
|
3107
|
-
|
|
3108
|
-
|
|
3406
|
+
const iterable = new AsyncIterableStream(
|
|
3407
|
+
call,
|
|
3408
|
+
{ onConnected, onError, onEnd },
|
|
3409
|
+
decodeJob
|
|
3410
|
+
);
|
|
3109
3411
|
return {
|
|
3110
3412
|
[Symbol.asyncIterator]() {
|
|
3111
3413
|
return iterable[Symbol.asyncIterator]();
|
|
@@ -3117,104 +3419,6 @@ function createJobStream(call, options) {
|
|
|
3117
3419
|
}
|
|
3118
3420
|
|
|
3119
3421
|
// src/grpc/client.ts
|
|
3120
|
-
function encodeStruct(value) {
|
|
3121
|
-
if (value == null) {
|
|
3122
|
-
return void 0;
|
|
3123
|
-
}
|
|
3124
|
-
return {
|
|
3125
|
-
fields: Object.fromEntries(
|
|
3126
|
-
Object.entries(value).map(([key, entry]) => [key, encodeValue(entry)])
|
|
3127
|
-
)
|
|
3128
|
-
};
|
|
3129
|
-
}
|
|
3130
|
-
function encodeValue(value) {
|
|
3131
|
-
if (value == null) {
|
|
3132
|
-
return { nullValue: 0 };
|
|
3133
|
-
}
|
|
3134
|
-
if (Array.isArray(value)) {
|
|
3135
|
-
return { listValue: { values: value.map(encodeValue) } };
|
|
3136
|
-
}
|
|
3137
|
-
switch (typeof value) {
|
|
3138
|
-
case "number":
|
|
3139
|
-
return { numberValue: value };
|
|
3140
|
-
case "string":
|
|
3141
|
-
return { stringValue: value };
|
|
3142
|
-
case "boolean":
|
|
3143
|
-
return { boolValue: value };
|
|
3144
|
-
case "object":
|
|
3145
|
-
return { structValue: encodeStruct(value) };
|
|
3146
|
-
default:
|
|
3147
|
-
return { stringValue: String(value) };
|
|
3148
|
-
}
|
|
3149
|
-
}
|
|
3150
|
-
function decodeStruct(value) {
|
|
3151
|
-
if (!value || typeof value !== "object" || !("fields" in value)) {
|
|
3152
|
-
return value;
|
|
3153
|
-
}
|
|
3154
|
-
const fields = value.fields ?? {};
|
|
3155
|
-
return Object.fromEntries(
|
|
3156
|
-
Object.entries(fields).map(([key, entry]) => [key, decodeValue(entry)])
|
|
3157
|
-
);
|
|
3158
|
-
}
|
|
3159
|
-
function decodeValue(value) {
|
|
3160
|
-
if ("nullValue" in value) {
|
|
3161
|
-
return null;
|
|
3162
|
-
}
|
|
3163
|
-
if ("numberValue" in value) {
|
|
3164
|
-
return value.numberValue;
|
|
3165
|
-
}
|
|
3166
|
-
if ("stringValue" in value) {
|
|
3167
|
-
return value.stringValue;
|
|
3168
|
-
}
|
|
3169
|
-
if ("boolValue" in value) {
|
|
3170
|
-
return value.boolValue;
|
|
3171
|
-
}
|
|
3172
|
-
if ("structValue" in value) {
|
|
3173
|
-
return decodeStruct(value.structValue);
|
|
3174
|
-
}
|
|
3175
|
-
if ("listValue" in value) {
|
|
3176
|
-
return (value.listValue.values ?? []).map(decodeValue);
|
|
3177
|
-
}
|
|
3178
|
-
return void 0;
|
|
3179
|
-
}
|
|
3180
|
-
function encodeEnqueueRequest(params) {
|
|
3181
|
-
const encoded = {
|
|
3182
|
-
queueName: params.queueName,
|
|
3183
|
-
payload: encodeStruct(params.payload)
|
|
3184
|
-
};
|
|
3185
|
-
if (params.priority !== void 0) {
|
|
3186
|
-
encoded.priority = params.priority;
|
|
3187
|
-
}
|
|
3188
|
-
if (params.maxRetries !== void 0) {
|
|
3189
|
-
encoded.maxRetries = params.maxRetries;
|
|
3190
|
-
}
|
|
3191
|
-
if (params.timeoutSeconds !== void 0) {
|
|
3192
|
-
encoded.timeoutSeconds = params.timeoutSeconds;
|
|
3193
|
-
}
|
|
3194
|
-
if (params.idempotencyKey !== void 0 && params.idempotencyKey !== "") {
|
|
3195
|
-
encoded.idempotencyKey = params.idempotencyKey;
|
|
3196
|
-
}
|
|
3197
|
-
if (params.scheduledAt !== void 0) {
|
|
3198
|
-
encoded.scheduledAt = params.scheduledAt;
|
|
3199
|
-
}
|
|
3200
|
-
if (params.tags !== void 0) {
|
|
3201
|
-
encoded.tags = params.tags;
|
|
3202
|
-
}
|
|
3203
|
-
return encoded;
|
|
3204
|
-
}
|
|
3205
|
-
function encodeCompleteRequest(params) {
|
|
3206
|
-
return {
|
|
3207
|
-
...params,
|
|
3208
|
-
result: encodeStruct(params.result)
|
|
3209
|
-
};
|
|
3210
|
-
}
|
|
3211
|
-
function decodeJob(job) {
|
|
3212
|
-
return {
|
|
3213
|
-
...job,
|
|
3214
|
-
payload: decodeStruct(job.payload),
|
|
3215
|
-
result: decodeStruct(job.result)
|
|
3216
|
-
};
|
|
3217
|
-
}
|
|
3218
3422
|
function promisify(client, method, request, metadata, timeoutMs) {
|
|
3219
3423
|
return new Promise((resolve, reject) => {
|
|
3220
3424
|
const callback = (error, response) => {
|
|
@@ -3794,6 +3998,17 @@ var SpooledClient = class _SpooledClient {
|
|
|
3794
3998
|
getConfig() {
|
|
3795
3999
|
return this.config;
|
|
3796
4000
|
}
|
|
4001
|
+
/**
|
|
4002
|
+
* Rate-limit state from the most recent response that carried
|
|
4003
|
+
* `X-RateLimit-*` headers (API 0.1.122+): `limit`, `remaining`, `reset`
|
|
4004
|
+
* (from the Unix-seconds header), `scope` and, after a 429, `retryAfter`.
|
|
4005
|
+
* `undefined` until such a response arrives, and for servers or routes that
|
|
4006
|
+
* do not send the headers. A 429 also carries the same values on
|
|
4007
|
+
* `RateLimitError.rateLimitInfo`.
|
|
4008
|
+
*/
|
|
4009
|
+
getRateLimitInfo() {
|
|
4010
|
+
return this.http.getLastRateLimitInfo();
|
|
4011
|
+
}
|
|
3797
4012
|
/**
|
|
3798
4013
|
* Get circuit breaker statistics
|
|
3799
4014
|
*/
|
|
@@ -4392,6 +4607,6 @@ var SpooledWorker = class {
|
|
|
4392
4607
|
}
|
|
4393
4608
|
};
|
|
4394
4609
|
|
|
4395
|
-
export { API_VERSION, AdminResource, ApiKeysResource, AuthResource, AuthenticationError, AuthorizationError, BillingResource, CircuitBreaker, CircuitBreakerOpenError, CircuitState, ConflictError, DEFAULT_CONFIG, DashboardResource, GrpcJobStatus, GrpcJobStatusNumber, GrpcQueueOperations, GrpcWorkerOperations, HealthResource, HttpClient, JobsResource, MetricsResource, NetworkError, NotFoundError, OrganizationsResource, PROTO_LOADER_OPTIONS, PayloadTooLargeError, QueuesResource, RateLimitError, SDK_VERSION, SchedulesResource, ServerError, SpooledClient, SpooledError, SpooledGrpcClient, SpooledRealtime, SpooledWorker, SseRealtimeClient, TimeoutError, UnsupportedOperationError, ValidationError, WebSocketRealtimeClient, WebhookIngestionResource, WebhooksResource, WorkersResource, WorkflowsResource, asyncIterableFromStream, calculateDelay, camelToSnake, clearProtoCache, convertQueryParams, convertRequest, convertResponse, createCircuitBreaker, createClient, createErrorFromResponse, createHttpClient, createJobStream, createPaginatedResponse, createProcessJobsStream, createRetryWrapper, dateToTimestamp, getProtoPath, isRetryableError, isSpooledError, loadProtoDefinition, loadProtoDefinitionAsync, parseRateLimitHeaders, resolveConfig, shouldRetry, sleep, snakeToCamel, timestampToDate, toCamelCase, toSnakeCase, validateConfig, withRetry };
|
|
4610
|
+
export { API_VERSION, AdminResource, ApiKeysResource, AuthResource, AuthenticationError, AuthorizationError, BillingResource, CircuitBreaker, CircuitBreakerOpenError, CircuitState, ConflictError, DEFAULT_CONFIG, DashboardResource, GrpcJobStatus, GrpcJobStatusNumber, GrpcQueueOperations, GrpcWorkerOperations, HealthResource, HttpClient, JobsResource, MetricsResource, NetworkError, NotFoundError, OrganizationsResource, PROTO_LOADER_OPTIONS, PayloadTooLargeError, QueuesResource, RateLimitError, SDK_VERSION, SchedulesResource, ServerError, SpooledClient, SpooledError, SpooledGrpcClient, SpooledRealtime, SpooledWorker, SseRealtimeClient, TimeoutError, UnsupportedOperationError, ValidationError, WebSocketRealtimeClient, WebhookIngestionResource, WebhooksResource, WorkersResource, WorkflowsResource, asyncIterableFromStream, calculateDelay, camelToSnake, clearProtoCache, convertQueryParams, convertRequest, convertResponse, createCircuitBreaker, createClient, createErrorFromResponse, createHttpClient, createJobStream, createPaginatedResponse, createProcessJobsStream, createRetryWrapper, dateToTimestamp, getProtoPath, isCircuitBreakerFailure, isRetryableError, isSpooledError, loadProtoDefinition, loadProtoDefinitionAsync, parseRateLimitHeaders, resolveConfig, shouldRetry, sleep, snakeToCamel, timestampToDate, toCamelCase, toSnakeCase, validateConfig, withRetry };
|
|
4396
4611
|
//# sourceMappingURL=index.js.map
|
|
4397
4612
|
//# sourceMappingURL=index.js.map
|