@spooled/sdk 1.0.38 → 1.0.40
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 +116 -94
- package/dist/{index-D_Lb9_Bg.d.cts → index-DA_znF4h.d.cts} +80 -66
- package/dist/{index-D_Lb9_Bg.d.ts → index-DA_znF4h.d.ts} +80 -66
- package/dist/index.cjs +387 -95
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +388 -97
- package/dist/index.js.map +1 -1
- package/dist/worker/index.cjs +14 -5
- 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 +14 -5
- package/dist/worker/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -2,8 +2,9 @@ import { createHmac } from 'crypto';
|
|
|
2
2
|
import { Buffer } from 'buffer';
|
|
3
3
|
import * as grpc2 from '@grpc/grpc-js';
|
|
4
4
|
import * as protoLoader from '@grpc/proto-loader';
|
|
5
|
+
import { existsSync } from 'fs';
|
|
5
6
|
import { fileURLToPath } from 'url';
|
|
6
|
-
import {
|
|
7
|
+
import { join, dirname } from 'path';
|
|
7
8
|
import { hostname } from 'os';
|
|
8
9
|
|
|
9
10
|
// src/config.ts
|
|
@@ -25,10 +26,10 @@ var DEFAULT_CONFIG = {
|
|
|
25
26
|
successThreshold: 3,
|
|
26
27
|
timeout: 3e4
|
|
27
28
|
},
|
|
28
|
-
userAgent: "@spooled/sdk-nodejs/1.0.
|
|
29
|
+
userAgent: "@spooled/sdk-nodejs/1.0.40",
|
|
29
30
|
autoRefreshToken: true
|
|
30
31
|
};
|
|
31
|
-
var SDK_VERSION = "1.0.
|
|
32
|
+
var SDK_VERSION = "1.0.40";
|
|
32
33
|
var API_VERSION = "v1";
|
|
33
34
|
var API_BASE_PATH = `/api/${API_VERSION}`;
|
|
34
35
|
function normalizeCredential(value) {
|
|
@@ -354,13 +355,31 @@ async function createErrorFromResponse(response) {
|
|
|
354
355
|
return new PayloadTooLargeError(message, code, details, requestId);
|
|
355
356
|
case 429: {
|
|
356
357
|
const rateLimitInfo = parseRateLimitHeaders(response.headers);
|
|
357
|
-
return new RateLimitError(
|
|
358
|
+
return new RateLimitError(
|
|
359
|
+
message,
|
|
360
|
+
code,
|
|
361
|
+
rateLimitInfo,
|
|
362
|
+
details,
|
|
363
|
+
requestId
|
|
364
|
+
);
|
|
358
365
|
}
|
|
359
366
|
default:
|
|
360
367
|
if (response.status >= 500) {
|
|
361
|
-
return new ServerError(
|
|
368
|
+
return new ServerError(
|
|
369
|
+
message,
|
|
370
|
+
response.status,
|
|
371
|
+
code,
|
|
372
|
+
details,
|
|
373
|
+
requestId
|
|
374
|
+
);
|
|
362
375
|
}
|
|
363
|
-
return new SpooledError(
|
|
376
|
+
return new SpooledError(
|
|
377
|
+
message,
|
|
378
|
+
response.status,
|
|
379
|
+
code,
|
|
380
|
+
details,
|
|
381
|
+
requestId
|
|
382
|
+
);
|
|
364
383
|
}
|
|
365
384
|
}
|
|
366
385
|
function isSpooledError(error) {
|
|
@@ -618,7 +637,9 @@ var HttpClient = class {
|
|
|
618
637
|
if (externalSignal.aborted) {
|
|
619
638
|
controller.abort();
|
|
620
639
|
} else {
|
|
621
|
-
externalSignal.addEventListener("abort", () => controller.abort(), {
|
|
640
|
+
externalSignal.addEventListener("abort", () => controller.abort(), {
|
|
641
|
+
once: true
|
|
642
|
+
});
|
|
622
643
|
}
|
|
623
644
|
}
|
|
624
645
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -633,7 +654,10 @@ var HttpClient = class {
|
|
|
633
654
|
if (externalSignal?.aborted) {
|
|
634
655
|
throw error;
|
|
635
656
|
}
|
|
636
|
-
throw new TimeoutError(
|
|
657
|
+
throw new TimeoutError(
|
|
658
|
+
`Request timed out after ${timeoutMs}ms`,
|
|
659
|
+
timeoutMs
|
|
660
|
+
);
|
|
637
661
|
}
|
|
638
662
|
throw error;
|
|
639
663
|
} finally {
|
|
@@ -662,13 +686,21 @@ var HttpClient = class {
|
|
|
662
686
|
this.debug?.(`${method} ${url}`, { timeout, hasBody: !!options.body });
|
|
663
687
|
let response;
|
|
664
688
|
try {
|
|
665
|
-
response = await this.fetchWithTimeout(
|
|
689
|
+
response = await this.fetchWithTimeout(
|
|
690
|
+
url,
|
|
691
|
+
init,
|
|
692
|
+
timeout,
|
|
693
|
+
options.signal
|
|
694
|
+
);
|
|
666
695
|
} catch (error) {
|
|
667
696
|
if (error instanceof TimeoutError || error instanceof SpooledError) {
|
|
668
697
|
throw error;
|
|
669
698
|
}
|
|
670
699
|
const cause = error instanceof Error ? error : void 0;
|
|
671
|
-
throw new NetworkError(
|
|
700
|
+
throw new NetworkError(
|
|
701
|
+
`Network request failed: ${cause?.message ?? "Unknown error"}`,
|
|
702
|
+
cause
|
|
703
|
+
);
|
|
672
704
|
}
|
|
673
705
|
this.debug?.(`Response: ${response.status}`, { url });
|
|
674
706
|
if (!response.ok) {
|
|
@@ -715,7 +747,9 @@ var HttpClient = class {
|
|
|
715
747
|
const url = this.buildUrl(path, options.params, options.skipApiPrefix);
|
|
716
748
|
const method = options.method ?? "GET";
|
|
717
749
|
const execute = async () => {
|
|
718
|
-
return this.circuitBreaker.execute(
|
|
750
|
+
return this.circuitBreaker.execute(
|
|
751
|
+
() => this.executeRequest(url, options)
|
|
752
|
+
);
|
|
719
753
|
};
|
|
720
754
|
if (options.skipRetry) {
|
|
721
755
|
return execute();
|
|
@@ -724,7 +758,9 @@ var HttpClient = class {
|
|
|
724
758
|
config: this.resolveRetryConfig(method, options),
|
|
725
759
|
signal: options.signal,
|
|
726
760
|
onRetry: (attempt, error, delayMs) => {
|
|
727
|
-
this.debug?.(`Retry attempt ${attempt} after ${delayMs}ms`, {
|
|
761
|
+
this.debug?.(`Retry attempt ${attempt} after ${delayMs}ms`, {
|
|
762
|
+
error: error.message
|
|
763
|
+
});
|
|
728
764
|
}
|
|
729
765
|
});
|
|
730
766
|
}
|
|
@@ -736,7 +772,9 @@ var HttpClient = class {
|
|
|
736
772
|
if (!options.headers) {
|
|
737
773
|
return false;
|
|
738
774
|
}
|
|
739
|
-
return Object.keys(options.headers).some(
|
|
775
|
+
return Object.keys(options.headers).some(
|
|
776
|
+
(key) => key.toLowerCase() === "idempotency-key"
|
|
777
|
+
);
|
|
740
778
|
}
|
|
741
779
|
/**
|
|
742
780
|
* Resolve the retry configuration for a request.
|
|
@@ -774,28 +812,43 @@ var HttpClient = class {
|
|
|
774
812
|
* Make a POST request
|
|
775
813
|
*/
|
|
776
814
|
async post(path, body, options) {
|
|
777
|
-
const response = await this.request(path, {
|
|
815
|
+
const response = await this.request(path, {
|
|
816
|
+
...options,
|
|
817
|
+
method: "POST",
|
|
818
|
+
body
|
|
819
|
+
});
|
|
778
820
|
return response.data;
|
|
779
821
|
}
|
|
780
822
|
/**
|
|
781
823
|
* Make a PUT request
|
|
782
824
|
*/
|
|
783
825
|
async put(path, body, options) {
|
|
784
|
-
const response = await this.request(path, {
|
|
826
|
+
const response = await this.request(path, {
|
|
827
|
+
...options,
|
|
828
|
+
method: "PUT",
|
|
829
|
+
body
|
|
830
|
+
});
|
|
785
831
|
return response.data;
|
|
786
832
|
}
|
|
787
833
|
/**
|
|
788
834
|
* Make a PATCH request
|
|
789
835
|
*/
|
|
790
836
|
async patch(path, body, options) {
|
|
791
|
-
const response = await this.request(path, {
|
|
837
|
+
const response = await this.request(path, {
|
|
838
|
+
...options,
|
|
839
|
+
method: "PATCH",
|
|
840
|
+
body
|
|
841
|
+
});
|
|
792
842
|
return response.data;
|
|
793
843
|
}
|
|
794
844
|
/**
|
|
795
845
|
* Make a DELETE request
|
|
796
846
|
*/
|
|
797
847
|
async delete(path, options) {
|
|
798
|
-
const response = await this.request(path, {
|
|
848
|
+
const response = await this.request(path, {
|
|
849
|
+
...options,
|
|
850
|
+
method: "DELETE"
|
|
851
|
+
});
|
|
799
852
|
return response.data;
|
|
800
853
|
}
|
|
801
854
|
};
|
|
@@ -989,7 +1042,10 @@ var AuthResource = class {
|
|
|
989
1042
|
*/
|
|
990
1043
|
async logout(refreshToken) {
|
|
991
1044
|
const token = refreshToken ?? this.getRefreshToken?.();
|
|
992
|
-
await this.http.post(
|
|
1045
|
+
await this.http.post(
|
|
1046
|
+
"/auth/logout",
|
|
1047
|
+
token ? { refreshToken: token } : void 0
|
|
1048
|
+
);
|
|
993
1049
|
}
|
|
994
1050
|
/**
|
|
995
1051
|
* Get current user/session info
|
|
@@ -1007,7 +1063,10 @@ var AuthResource = class {
|
|
|
1007
1063
|
* Start email-based login flow (sends magic link)
|
|
1008
1064
|
*/
|
|
1009
1065
|
async startEmailLogin(email) {
|
|
1010
|
-
return this.http.post(
|
|
1066
|
+
return this.http.post(
|
|
1067
|
+
"/auth/email/start",
|
|
1068
|
+
{ email }
|
|
1069
|
+
);
|
|
1011
1070
|
}
|
|
1012
1071
|
/**
|
|
1013
1072
|
* Check if an email address exists in the system
|
|
@@ -1048,7 +1107,9 @@ var JobsResource = class {
|
|
|
1048
1107
|
* List jobs with optional filtering
|
|
1049
1108
|
*/
|
|
1050
1109
|
async list(params) {
|
|
1051
|
-
return this.http.get("/jobs", {
|
|
1110
|
+
return this.http.get("/jobs", {
|
|
1111
|
+
params
|
|
1112
|
+
});
|
|
1052
1113
|
}
|
|
1053
1114
|
/**
|
|
1054
1115
|
* Get a job by ID
|
|
@@ -1072,7 +1133,9 @@ var JobsResource = class {
|
|
|
1072
1133
|
* Boost job priority
|
|
1073
1134
|
*/
|
|
1074
1135
|
async boostPriority(id, priority) {
|
|
1075
|
-
return this.http.put(`/jobs/${id}/priority`, {
|
|
1136
|
+
return this.http.put(`/jobs/${id}/priority`, {
|
|
1137
|
+
priority
|
|
1138
|
+
});
|
|
1076
1139
|
}
|
|
1077
1140
|
/**
|
|
1078
1141
|
* Get job statistics
|
|
@@ -1117,17 +1180,25 @@ var JobsResource = class {
|
|
|
1117
1180
|
* Fail a job (worker nack)
|
|
1118
1181
|
*/
|
|
1119
1182
|
async fail(id, params) {
|
|
1120
|
-
return this.http.post(
|
|
1183
|
+
return this.http.post(
|
|
1184
|
+
`/jobs/${id}/fail`,
|
|
1185
|
+
params
|
|
1186
|
+
);
|
|
1121
1187
|
}
|
|
1122
1188
|
/**
|
|
1123
1189
|
* Extend job lease (heartbeat)
|
|
1124
1190
|
*/
|
|
1125
1191
|
async heartbeat(id, params) {
|
|
1126
|
-
return this.http.post(
|
|
1192
|
+
return this.http.post(
|
|
1193
|
+
`/jobs/${id}/heartbeat`,
|
|
1194
|
+
params
|
|
1195
|
+
);
|
|
1127
1196
|
}
|
|
1128
1197
|
// DLQ operations (private implementations)
|
|
1129
1198
|
async listDlq(params) {
|
|
1130
|
-
return this.http.get("/jobs/dlq", {
|
|
1199
|
+
return this.http.get("/jobs/dlq", {
|
|
1200
|
+
params
|
|
1201
|
+
});
|
|
1131
1202
|
}
|
|
1132
1203
|
async retryDlq(params) {
|
|
1133
1204
|
return this.http.post("/jobs/dlq/retry", params);
|
|
@@ -1158,13 +1229,18 @@ var QueuesResource = class {
|
|
|
1158
1229
|
* Update queue configuration
|
|
1159
1230
|
*/
|
|
1160
1231
|
async updateConfig(name, params) {
|
|
1161
|
-
return this.http.put(
|
|
1232
|
+
return this.http.put(
|
|
1233
|
+
`/queues/${encodeURIComponent(name)}/config`,
|
|
1234
|
+
params
|
|
1235
|
+
);
|
|
1162
1236
|
}
|
|
1163
1237
|
/**
|
|
1164
1238
|
* Get queue statistics
|
|
1165
1239
|
*/
|
|
1166
1240
|
async getStats(name) {
|
|
1167
|
-
return this.http.get(
|
|
1241
|
+
return this.http.get(
|
|
1242
|
+
`/queues/${encodeURIComponent(name)}/stats`
|
|
1243
|
+
);
|
|
1168
1244
|
}
|
|
1169
1245
|
/**
|
|
1170
1246
|
* Pause a queue
|
|
@@ -1179,7 +1255,9 @@ var QueuesResource = class {
|
|
|
1179
1255
|
* Resume a paused queue
|
|
1180
1256
|
*/
|
|
1181
1257
|
async resume(name) {
|
|
1182
|
-
return this.http.post(
|
|
1258
|
+
return this.http.post(
|
|
1259
|
+
`/queues/${encodeURIComponent(name)}/resume`
|
|
1260
|
+
);
|
|
1183
1261
|
}
|
|
1184
1262
|
/**
|
|
1185
1263
|
* Delete a queue configuration
|
|
@@ -1235,7 +1313,9 @@ var SchedulesResource = class {
|
|
|
1235
1313
|
* List all schedules
|
|
1236
1314
|
*/
|
|
1237
1315
|
async list(params) {
|
|
1238
|
-
return this.http.get("/schedules", {
|
|
1316
|
+
return this.http.get("/schedules", {
|
|
1317
|
+
params
|
|
1318
|
+
});
|
|
1239
1319
|
}
|
|
1240
1320
|
/**
|
|
1241
1321
|
* Create a new schedule
|
|
@@ -1307,7 +1387,9 @@ var WorkflowsResource = class {
|
|
|
1307
1387
|
* List all workflows
|
|
1308
1388
|
*/
|
|
1309
1389
|
async list(params) {
|
|
1310
|
-
return this.http.get("/workflows", {
|
|
1390
|
+
return this.http.get("/workflows", {
|
|
1391
|
+
params
|
|
1392
|
+
});
|
|
1311
1393
|
}
|
|
1312
1394
|
/**
|
|
1313
1395
|
* Create a new workflow
|
|
@@ -1344,13 +1426,18 @@ var WorkflowsResource = class {
|
|
|
1344
1426
|
return this.http.get(`/workflows/${workflowId}/jobs/${jobId}`);
|
|
1345
1427
|
}
|
|
1346
1428
|
async getWorkflowJobsStatus(workflowId) {
|
|
1347
|
-
return this.http.get(
|
|
1429
|
+
return this.http.get(
|
|
1430
|
+
`/workflows/${workflowId}/jobs/status`
|
|
1431
|
+
);
|
|
1348
1432
|
}
|
|
1349
1433
|
async getJobDependencies(jobId) {
|
|
1350
1434
|
return this.http.get(`/jobs/${jobId}/dependencies`);
|
|
1351
1435
|
}
|
|
1352
1436
|
async addJobDependencies(jobId, params) {
|
|
1353
|
-
return this.http.post(
|
|
1437
|
+
return this.http.post(
|
|
1438
|
+
`/jobs/${jobId}/dependencies`,
|
|
1439
|
+
params
|
|
1440
|
+
);
|
|
1354
1441
|
}
|
|
1355
1442
|
};
|
|
1356
1443
|
|
|
@@ -1399,7 +1486,9 @@ var WebhooksResource = class {
|
|
|
1399
1486
|
* Get webhook delivery history
|
|
1400
1487
|
*/
|
|
1401
1488
|
async getDeliveries(id) {
|
|
1402
|
-
return this.http.get(
|
|
1489
|
+
return this.http.get(
|
|
1490
|
+
`/outgoing-webhooks/${id}/deliveries`
|
|
1491
|
+
);
|
|
1403
1492
|
}
|
|
1404
1493
|
/**
|
|
1405
1494
|
* Retry a specific webhook delivery
|
|
@@ -1507,7 +1596,9 @@ var OrganizationsResource = class {
|
|
|
1507
1596
|
* Generate a unique slug from an organization name
|
|
1508
1597
|
*/
|
|
1509
1598
|
async generateSlug(name) {
|
|
1510
|
-
return this.http.post("/organizations/generate-slug", {
|
|
1599
|
+
return this.http.post("/organizations/generate-slug", {
|
|
1600
|
+
name
|
|
1601
|
+
});
|
|
1511
1602
|
}
|
|
1512
1603
|
/**
|
|
1513
1604
|
* Get the webhook token for the current organization.
|
|
@@ -1537,7 +1628,9 @@ var OrganizationsResource = class {
|
|
|
1537
1628
|
* ```
|
|
1538
1629
|
*/
|
|
1539
1630
|
async regenerateWebhookToken() {
|
|
1540
|
-
return this.http.post(
|
|
1631
|
+
return this.http.post(
|
|
1632
|
+
"/organizations/webhook-token/regenerate"
|
|
1633
|
+
);
|
|
1541
1634
|
}
|
|
1542
1635
|
/**
|
|
1543
1636
|
* Clear/delete the webhook token for the current organization.
|
|
@@ -1574,7 +1667,10 @@ var BillingResource = class {
|
|
|
1574
1667
|
* POST /api/v1/billing/portal
|
|
1575
1668
|
*/
|
|
1576
1669
|
async createPortal(params) {
|
|
1577
|
-
return this.http.post(
|
|
1670
|
+
return this.http.post(
|
|
1671
|
+
"/billing/portal",
|
|
1672
|
+
params
|
|
1673
|
+
);
|
|
1578
1674
|
}
|
|
1579
1675
|
};
|
|
1580
1676
|
|
|
@@ -1669,7 +1765,9 @@ var AdminResource = class {
|
|
|
1669
1765
|
}
|
|
1670
1766
|
headers() {
|
|
1671
1767
|
if (!this.adminKey) {
|
|
1672
|
-
throw new AuthenticationError(
|
|
1768
|
+
throw new AuthenticationError(
|
|
1769
|
+
"Admin key is required for admin endpoints. Provide `adminKey` in SpooledClient config."
|
|
1770
|
+
);
|
|
1673
1771
|
}
|
|
1674
1772
|
return { "X-Admin-Key": this.adminKey };
|
|
1675
1773
|
}
|
|
@@ -1690,15 +1788,22 @@ var AdminResource = class {
|
|
|
1690
1788
|
}
|
|
1691
1789
|
/** POST /api/v1/admin/organizations */
|
|
1692
1790
|
async createOrganization(params) {
|
|
1693
|
-
return this.http.post(
|
|
1694
|
-
|
|
1695
|
-
|
|
1791
|
+
return this.http.post(
|
|
1792
|
+
"/admin/organizations",
|
|
1793
|
+
params,
|
|
1794
|
+
{
|
|
1795
|
+
headers: this.headers()
|
|
1796
|
+
}
|
|
1797
|
+
);
|
|
1696
1798
|
}
|
|
1697
1799
|
/** GET /api/v1/admin/organizations/{id} */
|
|
1698
1800
|
async getOrganization(id) {
|
|
1699
|
-
return this.http.get(
|
|
1700
|
-
|
|
1701
|
-
|
|
1801
|
+
return this.http.get(
|
|
1802
|
+
`/admin/organizations/${id}`,
|
|
1803
|
+
{
|
|
1804
|
+
headers: this.headers()
|
|
1805
|
+
}
|
|
1806
|
+
);
|
|
1702
1807
|
}
|
|
1703
1808
|
/** PATCH /api/v1/admin/organizations/{id} */
|
|
1704
1809
|
async updateOrganization(id, params) {
|
|
@@ -1716,15 +1821,23 @@ var AdminResource = class {
|
|
|
1716
1821
|
}
|
|
1717
1822
|
/** POST /api/v1/admin/organizations/{id}/api-keys */
|
|
1718
1823
|
async createApiKey(orgId, params) {
|
|
1719
|
-
return this.http.post(
|
|
1720
|
-
|
|
1721
|
-
|
|
1824
|
+
return this.http.post(
|
|
1825
|
+
`/admin/organizations/${orgId}/api-keys`,
|
|
1826
|
+
params,
|
|
1827
|
+
{
|
|
1828
|
+
headers: this.headers()
|
|
1829
|
+
}
|
|
1830
|
+
);
|
|
1722
1831
|
}
|
|
1723
1832
|
/** POST /api/v1/admin/organizations/{id}/reset-usage */
|
|
1724
1833
|
async resetUsage(orgId) {
|
|
1725
|
-
await this.http.post(
|
|
1726
|
-
|
|
1727
|
-
|
|
1834
|
+
await this.http.post(
|
|
1835
|
+
`/admin/organizations/${orgId}/reset-usage`,
|
|
1836
|
+
void 0,
|
|
1837
|
+
{
|
|
1838
|
+
headers: this.headers()
|
|
1839
|
+
}
|
|
1840
|
+
);
|
|
1728
1841
|
}
|
|
1729
1842
|
/** GET /api/v1/admin/stats */
|
|
1730
1843
|
async getStats() {
|
|
@@ -1770,7 +1883,9 @@ var WebhookIngestionResource = class {
|
|
|
1770
1883
|
const bytes = toBytes(body);
|
|
1771
1884
|
const signature = options.signature ?? (options.secret ? githubSignature(options.secret, bytes) : void 0);
|
|
1772
1885
|
if (!signature) {
|
|
1773
|
-
throw new ValidationError(
|
|
1886
|
+
throw new ValidationError(
|
|
1887
|
+
"GitHub webhook signature is required (provide `signature` or `secret`)"
|
|
1888
|
+
);
|
|
1774
1889
|
}
|
|
1775
1890
|
const headers = {
|
|
1776
1891
|
"Content-Type": "application/json",
|
|
@@ -1801,7 +1916,9 @@ var WebhookIngestionResource = class {
|
|
|
1801
1916
|
const timestamp = options.timestamp ?? Math.floor(Date.now() / 1e3);
|
|
1802
1917
|
const signature = options.signature ?? (options.secret ? stripeSignature(options.secret, bytes, timestamp) : void 0);
|
|
1803
1918
|
if (!signature) {
|
|
1804
|
-
throw new ValidationError(
|
|
1919
|
+
throw new ValidationError(
|
|
1920
|
+
"Stripe webhook signature is required (provide `signature` or `secret`)"
|
|
1921
|
+
);
|
|
1805
1922
|
}
|
|
1806
1923
|
const headers = {
|
|
1807
1924
|
"Content-Type": "application/json",
|
|
@@ -1938,14 +2055,20 @@ var WebSocketRealtimeClient = class {
|
|
|
1938
2055
|
resolve();
|
|
1939
2056
|
};
|
|
1940
2057
|
this.ws.onmessage = (event) => {
|
|
1941
|
-
this.handleMessage(
|
|
2058
|
+
this.handleMessage(
|
|
2059
|
+
typeof event.data === "string" ? event.data : String(event.data)
|
|
2060
|
+
);
|
|
1942
2061
|
};
|
|
1943
2062
|
this.ws.onclose = (event) => {
|
|
1944
2063
|
this.options.debug(`WebSocket closed: ${event.code} ${event.reason}`);
|
|
1945
2064
|
const wasConnecting = this.state === "connecting";
|
|
1946
2065
|
this.handleDisconnect();
|
|
1947
2066
|
if (wasConnecting) {
|
|
1948
|
-
reject(
|
|
2067
|
+
reject(
|
|
2068
|
+
new Error(
|
|
2069
|
+
`WebSocket connection failed: ${event.reason || "Unknown error"}`
|
|
2070
|
+
)
|
|
2071
|
+
);
|
|
1949
2072
|
}
|
|
1950
2073
|
};
|
|
1951
2074
|
this.ws.onerror = (event) => {
|
|
@@ -2100,7 +2223,9 @@ var WebSocketRealtimeClient = class {
|
|
|
2100
2223
|
this.options.maxReconnectDelay
|
|
2101
2224
|
);
|
|
2102
2225
|
const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);
|
|
2103
|
-
this.options.debug(
|
|
2226
|
+
this.options.debug(
|
|
2227
|
+
`Scheduling reconnect attempt ${this.reconnectAttempts} in ${delay}ms`
|
|
2228
|
+
);
|
|
2104
2229
|
this.reconnectTimer = setTimeout(async () => {
|
|
2105
2230
|
try {
|
|
2106
2231
|
await this.connect();
|
|
@@ -2153,11 +2278,13 @@ function isAuthFailureEvent(event) {
|
|
|
2153
2278
|
if (!event) {
|
|
2154
2279
|
return false;
|
|
2155
2280
|
}
|
|
2156
|
-
const
|
|
2157
|
-
if (
|
|
2281
|
+
const status2 = event.status ?? event.statusCode ?? event.error?.status;
|
|
2282
|
+
if (status2 === 401 || status2 === 403) {
|
|
2158
2283
|
return true;
|
|
2159
2284
|
}
|
|
2160
|
-
const text = String(
|
|
2285
|
+
const text = String(
|
|
2286
|
+
event.message ?? event.error?.message ?? event.reason ?? ""
|
|
2287
|
+
);
|
|
2161
2288
|
return /\b(401|403)\b/.test(text);
|
|
2162
2289
|
}
|
|
2163
2290
|
|
|
@@ -2220,7 +2347,9 @@ var SseRealtimeClient = class {
|
|
|
2220
2347
|
EventSourceImpl = mod.default || mod.EventSource || mod;
|
|
2221
2348
|
} catch {
|
|
2222
2349
|
this.setState("disconnected");
|
|
2223
|
-
throw new Error(
|
|
2350
|
+
throw new Error(
|
|
2351
|
+
"eventsource package is required for SSE in Node.js. Install it with: npm install eventsource"
|
|
2352
|
+
);
|
|
2224
2353
|
}
|
|
2225
2354
|
}
|
|
2226
2355
|
let token;
|
|
@@ -2389,7 +2518,9 @@ var SseRealtimeClient = class {
|
|
|
2389
2518
|
this.options.maxReconnectDelay
|
|
2390
2519
|
);
|
|
2391
2520
|
const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);
|
|
2392
|
-
this.options.debug(
|
|
2521
|
+
this.options.debug(
|
|
2522
|
+
`Scheduling SSE reconnect attempt ${this.reconnectAttempts} in ${delay}ms`
|
|
2523
|
+
);
|
|
2393
2524
|
this.reconnectTimer = setTimeout(async () => {
|
|
2394
2525
|
try {
|
|
2395
2526
|
await this.connect(this.filter || void 0);
|
|
@@ -2535,20 +2666,40 @@ var PROTO_LOADER_OPTIONS = {
|
|
|
2535
2666
|
// Support oneofs
|
|
2536
2667
|
};
|
|
2537
2668
|
var cachedDefinition = null;
|
|
2538
|
-
function
|
|
2669
|
+
function getModuleDir() {
|
|
2539
2670
|
if (typeof import.meta?.url !== "undefined") {
|
|
2540
|
-
|
|
2541
|
-
const __dirname2 = dirname(__filename);
|
|
2542
|
-
return join(__dirname2, "../../proto/spooled.proto");
|
|
2671
|
+
return dirname(fileURLToPath(import.meta.url));
|
|
2543
2672
|
}
|
|
2544
|
-
return
|
|
2673
|
+
return __dirname;
|
|
2674
|
+
}
|
|
2675
|
+
function getProtoPath() {
|
|
2676
|
+
const moduleDir = getModuleDir();
|
|
2677
|
+
const candidates = [
|
|
2678
|
+
// Bundled ESM/CJS: dist/index.js → ../proto/spooled.proto
|
|
2679
|
+
join(moduleDir, "../proto/spooled.proto"),
|
|
2680
|
+
// Source / unbundled: src/grpc/loader.ts → ../../proto/spooled.proto
|
|
2681
|
+
join(moduleDir, "../../proto/spooled.proto"),
|
|
2682
|
+
// Extra safety if moduleDir is package root
|
|
2683
|
+
join(moduleDir, "proto/spooled.proto")
|
|
2684
|
+
];
|
|
2685
|
+
for (const candidate of candidates) {
|
|
2686
|
+
if (existsSync(candidate)) {
|
|
2687
|
+
return candidate;
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
throw new Error(
|
|
2691
|
+
`Spooled gRPC proto not found. Tried: ${candidates.join(", ")}. Ensure the package's proto/spooled.proto is installed next to dist/.`
|
|
2692
|
+
);
|
|
2545
2693
|
}
|
|
2546
2694
|
function loadProtoDefinition() {
|
|
2547
2695
|
if (cachedDefinition) {
|
|
2548
2696
|
return cachedDefinition;
|
|
2549
2697
|
}
|
|
2550
2698
|
const protoPath = getProtoPath();
|
|
2551
|
-
const packageDefinition = protoLoader.loadSync(
|
|
2699
|
+
const packageDefinition = protoLoader.loadSync(
|
|
2700
|
+
protoPath,
|
|
2701
|
+
PROTO_LOADER_OPTIONS
|
|
2702
|
+
);
|
|
2552
2703
|
const grpcObject = grpc2.loadPackageDefinition(packageDefinition);
|
|
2553
2704
|
cachedDefinition = grpcObject;
|
|
2554
2705
|
return cachedDefinition;
|
|
@@ -2558,7 +2709,10 @@ async function loadProtoDefinitionAsync() {
|
|
|
2558
2709
|
return cachedDefinition;
|
|
2559
2710
|
}
|
|
2560
2711
|
const protoPath = getProtoPath();
|
|
2561
|
-
const packageDefinition = await protoLoader.load(
|
|
2712
|
+
const packageDefinition = await protoLoader.load(
|
|
2713
|
+
protoPath,
|
|
2714
|
+
PROTO_LOADER_OPTIONS
|
|
2715
|
+
);
|
|
2562
2716
|
const grpcObject = grpc2.loadPackageDefinition(packageDefinition);
|
|
2563
2717
|
cachedDefinition = grpcObject;
|
|
2564
2718
|
return cachedDefinition;
|
|
@@ -2575,7 +2729,11 @@ async function* asyncIterableFromStream(stream, options) {
|
|
|
2575
2729
|
stream.cancel();
|
|
2576
2730
|
});
|
|
2577
2731
|
}
|
|
2578
|
-
return yield* new AsyncIterableStream(stream, {
|
|
2732
|
+
return yield* new AsyncIterableStream(stream, {
|
|
2733
|
+
onConnected,
|
|
2734
|
+
onError,
|
|
2735
|
+
onEnd
|
|
2736
|
+
});
|
|
2579
2737
|
}
|
|
2580
2738
|
var AsyncIterableStream = class {
|
|
2581
2739
|
stream;
|
|
@@ -2604,8 +2762,8 @@ var AsyncIterableStream = class {
|
|
|
2604
2762
|
onEnd?.();
|
|
2605
2763
|
resolve?.();
|
|
2606
2764
|
});
|
|
2607
|
-
this.stream.on("status", (
|
|
2608
|
-
if (
|
|
2765
|
+
this.stream.on("status", (status2) => {
|
|
2766
|
+
if (status2.code === 0) {
|
|
2609
2767
|
onConnected?.();
|
|
2610
2768
|
}
|
|
2611
2769
|
});
|
|
@@ -2706,7 +2864,9 @@ function decodeStruct(value) {
|
|
|
2706
2864
|
return value;
|
|
2707
2865
|
}
|
|
2708
2866
|
const fields = value.fields ?? {};
|
|
2709
|
-
return Object.fromEntries(
|
|
2867
|
+
return Object.fromEntries(
|
|
2868
|
+
Object.entries(fields).map(([key, entry]) => [key, decodeValue(entry)])
|
|
2869
|
+
);
|
|
2710
2870
|
}
|
|
2711
2871
|
function decodeValue(value) {
|
|
2712
2872
|
if ("nullValue" in value) {
|
|
@@ -2755,7 +2915,10 @@ function encodeEnqueueRequest(params) {
|
|
|
2755
2915
|
return encoded;
|
|
2756
2916
|
}
|
|
2757
2917
|
function encodeCompleteRequest(params) {
|
|
2758
|
-
return {
|
|
2918
|
+
return {
|
|
2919
|
+
...params,
|
|
2920
|
+
result: encodeStruct(params.result)
|
|
2921
|
+
};
|
|
2759
2922
|
}
|
|
2760
2923
|
function decodeJob(job) {
|
|
2761
2924
|
return {
|
|
@@ -2764,17 +2927,60 @@ function decodeJob(job) {
|
|
|
2764
2927
|
result: decodeStruct(job.result)
|
|
2765
2928
|
};
|
|
2766
2929
|
}
|
|
2767
|
-
function promisify(client, method, request, metadata) {
|
|
2930
|
+
function promisify(client, method, request, metadata, timeoutMs) {
|
|
2768
2931
|
return new Promise((resolve, reject) => {
|
|
2769
|
-
|
|
2932
|
+
const callback = (error, response) => {
|
|
2770
2933
|
if (error) {
|
|
2771
|
-
reject(error);
|
|
2934
|
+
reject(mapGrpcError(error, timeoutMs));
|
|
2772
2935
|
} else {
|
|
2773
2936
|
resolve(response);
|
|
2774
2937
|
}
|
|
2775
|
-
}
|
|
2938
|
+
};
|
|
2939
|
+
method.call(
|
|
2940
|
+
client,
|
|
2941
|
+
request,
|
|
2942
|
+
metadata,
|
|
2943
|
+
createUnaryCallOptions(timeoutMs),
|
|
2944
|
+
callback
|
|
2945
|
+
);
|
|
2776
2946
|
});
|
|
2777
2947
|
}
|
|
2948
|
+
function createUnaryCallOptions(timeoutMs) {
|
|
2949
|
+
if (timeoutMs === void 0) {
|
|
2950
|
+
return {};
|
|
2951
|
+
}
|
|
2952
|
+
return { deadline: new Date(Date.now() + timeoutMs) };
|
|
2953
|
+
}
|
|
2954
|
+
function mapGrpcError(error, timeoutMs) {
|
|
2955
|
+
const message = error.details || error.message || "gRPC request failed";
|
|
2956
|
+
switch (error.code) {
|
|
2957
|
+
case grpc2.status.DEADLINE_EXCEEDED:
|
|
2958
|
+
return new TimeoutError(message, timeoutMs ?? 0);
|
|
2959
|
+
case grpc2.status.UNAUTHENTICATED:
|
|
2960
|
+
return new AuthenticationError(message, "AUTHENTICATION_FAILED");
|
|
2961
|
+
case grpc2.status.PERMISSION_DENIED:
|
|
2962
|
+
return new AuthorizationError(message, "ACCESS_DENIED");
|
|
2963
|
+
case grpc2.status.NOT_FOUND:
|
|
2964
|
+
return new NotFoundError(message, "NOT_FOUND");
|
|
2965
|
+
case grpc2.status.INVALID_ARGUMENT:
|
|
2966
|
+
case grpc2.status.OUT_OF_RANGE:
|
|
2967
|
+
return new ValidationError(message, "VALIDATION_ERROR");
|
|
2968
|
+
case grpc2.status.ALREADY_EXISTS:
|
|
2969
|
+
case grpc2.status.ABORTED:
|
|
2970
|
+
case grpc2.status.FAILED_PRECONDITION:
|
|
2971
|
+
return new ConflictError(message, "CONFLICT");
|
|
2972
|
+
case grpc2.status.RESOURCE_EXHAUSTED:
|
|
2973
|
+
return new RateLimitError(message, "RATE_LIMIT_EXCEEDED");
|
|
2974
|
+
case grpc2.status.UNAVAILABLE:
|
|
2975
|
+
case grpc2.status.CANCELLED:
|
|
2976
|
+
return new NetworkError(message, error);
|
|
2977
|
+
default:
|
|
2978
|
+
if (error.code >= grpc2.status.INTERNAL) {
|
|
2979
|
+
return new ServerError(message, 500, "GRPC_SERVER_ERROR");
|
|
2980
|
+
}
|
|
2981
|
+
return new ServerError(message, 500, "GRPC_ERROR");
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2778
2984
|
function shouldUseTls(address, explicitTls) {
|
|
2779
2985
|
if (explicitTls !== void 0) {
|
|
2780
2986
|
return explicitTls;
|
|
@@ -2783,53 +2989,99 @@ function shouldUseTls(address, explicitTls) {
|
|
|
2783
2989
|
return host !== "localhost" && host !== "127.0.0.1" && !host.startsWith("[::1]");
|
|
2784
2990
|
}
|
|
2785
2991
|
var GrpcQueueOperations = class {
|
|
2786
|
-
constructor(client, metadata) {
|
|
2992
|
+
constructor(client, metadata, timeoutMs) {
|
|
2787
2993
|
this.client = client;
|
|
2788
2994
|
this.metadata = metadata;
|
|
2995
|
+
this.timeoutMs = timeoutMs;
|
|
2789
2996
|
}
|
|
2790
2997
|
/**
|
|
2791
2998
|
* Enqueue a new job
|
|
2792
2999
|
*/
|
|
2793
3000
|
async enqueue(params) {
|
|
2794
|
-
return promisify(
|
|
3001
|
+
return promisify(
|
|
3002
|
+
this.client,
|
|
3003
|
+
this.client.Enqueue,
|
|
3004
|
+
encodeEnqueueRequest(params),
|
|
3005
|
+
this.metadata,
|
|
3006
|
+
this.timeoutMs
|
|
3007
|
+
);
|
|
2795
3008
|
}
|
|
2796
3009
|
/**
|
|
2797
3010
|
* Dequeue a job (for workers)
|
|
2798
3011
|
*/
|
|
2799
3012
|
async dequeue(params) {
|
|
2800
|
-
const response = await promisify(
|
|
3013
|
+
const response = await promisify(
|
|
3014
|
+
this.client,
|
|
3015
|
+
this.client.Dequeue,
|
|
3016
|
+
params,
|
|
3017
|
+
this.metadata,
|
|
3018
|
+
this.timeoutMs
|
|
3019
|
+
);
|
|
2801
3020
|
return { ...response, jobs: response.jobs.map(decodeJob) };
|
|
2802
3021
|
}
|
|
2803
3022
|
/**
|
|
2804
3023
|
* Complete a job successfully
|
|
2805
3024
|
*/
|
|
2806
3025
|
async complete(params) {
|
|
2807
|
-
return promisify(
|
|
3026
|
+
return promisify(
|
|
3027
|
+
this.client,
|
|
3028
|
+
this.client.Complete,
|
|
3029
|
+
encodeCompleteRequest(params),
|
|
3030
|
+
this.metadata,
|
|
3031
|
+
this.timeoutMs
|
|
3032
|
+
);
|
|
2808
3033
|
}
|
|
2809
3034
|
/**
|
|
2810
3035
|
* Fail a job
|
|
2811
3036
|
*/
|
|
2812
3037
|
async fail(params) {
|
|
2813
|
-
return promisify(
|
|
3038
|
+
return promisify(
|
|
3039
|
+
this.client,
|
|
3040
|
+
this.client.Fail,
|
|
3041
|
+
params,
|
|
3042
|
+
this.metadata,
|
|
3043
|
+
this.timeoutMs
|
|
3044
|
+
);
|
|
2814
3045
|
}
|
|
2815
3046
|
/**
|
|
2816
3047
|
* Renew a job's lease
|
|
2817
3048
|
*/
|
|
2818
3049
|
async renewLease(params) {
|
|
2819
|
-
return promisify(
|
|
3050
|
+
return promisify(
|
|
3051
|
+
this.client,
|
|
3052
|
+
this.client.RenewLease,
|
|
3053
|
+
params,
|
|
3054
|
+
this.metadata,
|
|
3055
|
+
this.timeoutMs
|
|
3056
|
+
);
|
|
2820
3057
|
}
|
|
2821
3058
|
/**
|
|
2822
3059
|
* Get a job by ID
|
|
2823
3060
|
*/
|
|
2824
3061
|
async getJob(jobId) {
|
|
2825
|
-
const response = await promisify(
|
|
2826
|
-
|
|
3062
|
+
const response = await promisify(
|
|
3063
|
+
this.client,
|
|
3064
|
+
this.client.GetJob,
|
|
3065
|
+
{ jobId },
|
|
3066
|
+
this.metadata,
|
|
3067
|
+
this.timeoutMs
|
|
3068
|
+
);
|
|
3069
|
+
return {
|
|
3070
|
+
...response,
|
|
3071
|
+
job: response.job ? decodeJob(response.job) : response.job
|
|
3072
|
+
};
|
|
2827
3073
|
}
|
|
2828
3074
|
/**
|
|
2829
3075
|
* Get queue statistics
|
|
2830
3076
|
*/
|
|
2831
3077
|
async getQueueStats(queueName) {
|
|
2832
|
-
return promisify(
|
|
3078
|
+
return promisify(
|
|
3079
|
+
this.client,
|
|
3080
|
+
this.client.GetQueueStats,
|
|
3081
|
+
{ queueName },
|
|
3082
|
+
this.metadata,
|
|
3083
|
+
this.timeoutMs
|
|
3084
|
+
);
|
|
2833
3085
|
}
|
|
2834
3086
|
/**
|
|
2835
3087
|
* Stream jobs from a queue (server-side streaming)
|
|
@@ -2877,27 +3129,46 @@ var GrpcQueueOperations = class {
|
|
|
2877
3129
|
}
|
|
2878
3130
|
};
|
|
2879
3131
|
var GrpcWorkerOperations = class {
|
|
2880
|
-
constructor(client, metadata) {
|
|
3132
|
+
constructor(client, metadata, timeoutMs) {
|
|
2881
3133
|
this.client = client;
|
|
2882
3134
|
this.metadata = metadata;
|
|
3135
|
+
this.timeoutMs = timeoutMs;
|
|
2883
3136
|
}
|
|
2884
3137
|
/**
|
|
2885
3138
|
* Register a new worker
|
|
2886
3139
|
*/
|
|
2887
3140
|
async register(params) {
|
|
2888
|
-
return promisify(
|
|
3141
|
+
return promisify(
|
|
3142
|
+
this.client,
|
|
3143
|
+
this.client.Register,
|
|
3144
|
+
params,
|
|
3145
|
+
this.metadata,
|
|
3146
|
+
this.timeoutMs
|
|
3147
|
+
);
|
|
2889
3148
|
}
|
|
2890
3149
|
/**
|
|
2891
3150
|
* Send heartbeat
|
|
2892
3151
|
*/
|
|
2893
3152
|
async heartbeat(params) {
|
|
2894
|
-
return promisify(
|
|
3153
|
+
return promisify(
|
|
3154
|
+
this.client,
|
|
3155
|
+
this.client.Heartbeat,
|
|
3156
|
+
params,
|
|
3157
|
+
this.metadata,
|
|
3158
|
+
this.timeoutMs
|
|
3159
|
+
);
|
|
2895
3160
|
}
|
|
2896
3161
|
/**
|
|
2897
3162
|
* Deregister a worker
|
|
2898
3163
|
*/
|
|
2899
3164
|
async deregister(workerId) {
|
|
2900
|
-
return promisify(
|
|
3165
|
+
return promisify(
|
|
3166
|
+
this.client,
|
|
3167
|
+
this.client.Deregister,
|
|
3168
|
+
{ workerId },
|
|
3169
|
+
this.metadata,
|
|
3170
|
+
this.timeoutMs
|
|
3171
|
+
);
|
|
2901
3172
|
}
|
|
2902
3173
|
};
|
|
2903
3174
|
var SpooledGrpcClient = class {
|
|
@@ -2909,7 +3180,7 @@ var SpooledGrpcClient = class {
|
|
|
2909
3180
|
/** Worker operations */
|
|
2910
3181
|
workers;
|
|
2911
3182
|
constructor(options) {
|
|
2912
|
-
const { address, apiKey, useTls, credentials: credentials2, channelOptions } = options;
|
|
3183
|
+
const { address, apiKey, useTls, credentials: credentials2, channelOptions, timeout } = options;
|
|
2913
3184
|
const creds = credentials2 ?? (shouldUseTls(address, useTls) ? grpc2.credentials.createSsl() : grpc2.credentials.createInsecure());
|
|
2914
3185
|
this.metadata = new grpc2.Metadata();
|
|
2915
3186
|
this.metadata.add("x-api-key", apiKey);
|
|
@@ -2924,8 +3195,16 @@ var SpooledGrpcClient = class {
|
|
|
2924
3195
|
creds,
|
|
2925
3196
|
channelOptions
|
|
2926
3197
|
);
|
|
2927
|
-
this.queue = new GrpcQueueOperations(
|
|
2928
|
-
|
|
3198
|
+
this.queue = new GrpcQueueOperations(
|
|
3199
|
+
this.queueClient,
|
|
3200
|
+
this.metadata,
|
|
3201
|
+
timeout
|
|
3202
|
+
);
|
|
3203
|
+
this.workers = new GrpcWorkerOperations(
|
|
3204
|
+
this.workerClient,
|
|
3205
|
+
this.metadata,
|
|
3206
|
+
timeout
|
|
3207
|
+
);
|
|
2929
3208
|
}
|
|
2930
3209
|
/**
|
|
2931
3210
|
* Close all gRPC connections
|
|
@@ -3074,7 +3353,8 @@ var SpooledClient = class _SpooledClient {
|
|
|
3074
3353
|
}
|
|
3075
3354
|
this._grpc = new SpooledGrpcClient({
|
|
3076
3355
|
address: grpcAddress,
|
|
3077
|
-
apiKey
|
|
3356
|
+
apiKey,
|
|
3357
|
+
timeout: this.config.timeout
|
|
3078
3358
|
});
|
|
3079
3359
|
}
|
|
3080
3360
|
return this._grpc;
|
|
@@ -3141,7 +3421,9 @@ var SpooledClient = class _SpooledClient {
|
|
|
3141
3421
|
}
|
|
3142
3422
|
return this.loginForJwt();
|
|
3143
3423
|
}
|
|
3144
|
-
throw new AuthenticationError(
|
|
3424
|
+
throw new AuthenticationError(
|
|
3425
|
+
"No authentication method available for realtime connection"
|
|
3426
|
+
);
|
|
3145
3427
|
}
|
|
3146
3428
|
/**
|
|
3147
3429
|
* Exchange the API key for a JWT via /auth/login and cache the result.
|
|
@@ -3438,7 +3720,10 @@ var SpooledWorker = class {
|
|
|
3438
3720
|
this.sendWorkerHeartbeat();
|
|
3439
3721
|
}, heartbeatInterval);
|
|
3440
3722
|
this.state = "running";
|
|
3441
|
-
this.emit("started", {
|
|
3723
|
+
this.emit("started", {
|
|
3724
|
+
workerId: this.workerId,
|
|
3725
|
+
queueName: this.options.queueName
|
|
3726
|
+
});
|
|
3442
3727
|
this.schedulePoll();
|
|
3443
3728
|
} catch (error) {
|
|
3444
3729
|
this.state = "error";
|
|
@@ -3474,14 +3759,18 @@ var SpooledWorker = class {
|
|
|
3474
3759
|
active.abortController.abort();
|
|
3475
3760
|
}
|
|
3476
3761
|
if (this.activeJobs.size > 0) {
|
|
3477
|
-
this.debug(
|
|
3762
|
+
this.debug(
|
|
3763
|
+
`Waiting for ${this.activeJobs.size} active jobs to complete...`
|
|
3764
|
+
);
|
|
3478
3765
|
await Promise.race([
|
|
3479
3766
|
this.waitForActiveJobs(),
|
|
3480
3767
|
this.sleep(this.options.shutdownTimeout)
|
|
3481
3768
|
]);
|
|
3482
3769
|
const remaining = Array.from(this.activeJobs.values());
|
|
3483
3770
|
for (const active of remaining) {
|
|
3484
|
-
this.debug(
|
|
3771
|
+
this.debug(
|
|
3772
|
+
`Force-failing job ${active.job.id} due to shutdown timeout`
|
|
3773
|
+
);
|
|
3485
3774
|
await this.failJob(active.job, "Worker shutdown timeout");
|
|
3486
3775
|
this.cleanupJob(active);
|
|
3487
3776
|
}
|
|
@@ -3589,7 +3878,9 @@ var SpooledWorker = class {
|
|
|
3589
3878
|
retryCount: job.retryCount,
|
|
3590
3879
|
maxRetries: job.maxRetries,
|
|
3591
3880
|
signal,
|
|
3592
|
-
progress: async (
|
|
3881
|
+
progress: async (percent, message) => {
|
|
3882
|
+
const boundedPercent = Math.max(0, Math.min(100, percent));
|
|
3883
|
+
this.debug(`[${job.id}] progress ${boundedPercent}%`, message);
|
|
3593
3884
|
},
|
|
3594
3885
|
log: (level, message, meta) => {
|
|
3595
3886
|
this.debug(`[${job.id}] [${level}] ${message}`, meta);
|
|
@@ -3692,6 +3983,6 @@ var SpooledWorker = class {
|
|
|
3692
3983
|
}
|
|
3693
3984
|
};
|
|
3694
3985
|
|
|
3695
|
-
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, ValidationError, WebSocketRealtimeClient, WebhookIngestionResource, WebhooksResource, WorkersResource, WorkflowsResource, asyncIterableFromStream, calculateDelay, camelToSnake, clearProtoCache, convertQueryParams, convertRequest, convertResponse, createCircuitBreaker, createClient, createErrorFromResponse, createHttpClient, createJobStream, createPaginatedResponse, createProcessJobsStream, createRetryWrapper, dateToTimestamp, isRetryableError, isSpooledError, loadProtoDefinition, loadProtoDefinitionAsync, parseRateLimitHeaders, resolveConfig, shouldRetry, sleep, snakeToCamel, timestampToDate, toCamelCase, toSnakeCase, validateConfig, withRetry };
|
|
3986
|
+
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, 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 };
|
|
3696
3987
|
//# sourceMappingURL=index.js.map
|
|
3697
3988
|
//# sourceMappingURL=index.js.map
|