@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.cjs
CHANGED
|
@@ -4,6 +4,7 @@ var crypto = require('crypto');
|
|
|
4
4
|
var buffer = require('buffer');
|
|
5
5
|
var grpc2 = require('@grpc/grpc-js');
|
|
6
6
|
var protoLoader = require('@grpc/proto-loader');
|
|
7
|
+
var fs = require('fs');
|
|
7
8
|
var url = require('url');
|
|
8
9
|
var path = require('path');
|
|
9
10
|
var os = require('os');
|
|
@@ -49,10 +50,10 @@ var DEFAULT_CONFIG = {
|
|
|
49
50
|
successThreshold: 3,
|
|
50
51
|
timeout: 3e4
|
|
51
52
|
},
|
|
52
|
-
userAgent: "@spooled/sdk-nodejs/1.0.
|
|
53
|
+
userAgent: "@spooled/sdk-nodejs/1.0.40",
|
|
53
54
|
autoRefreshToken: true
|
|
54
55
|
};
|
|
55
|
-
var SDK_VERSION = "1.0.
|
|
56
|
+
var SDK_VERSION = "1.0.40";
|
|
56
57
|
var API_VERSION = "v1";
|
|
57
58
|
var API_BASE_PATH = `/api/${API_VERSION}`;
|
|
58
59
|
function normalizeCredential(value) {
|
|
@@ -378,13 +379,31 @@ async function createErrorFromResponse(response) {
|
|
|
378
379
|
return new PayloadTooLargeError(message, code, details, requestId);
|
|
379
380
|
case 429: {
|
|
380
381
|
const rateLimitInfo = parseRateLimitHeaders(response.headers);
|
|
381
|
-
return new RateLimitError(
|
|
382
|
+
return new RateLimitError(
|
|
383
|
+
message,
|
|
384
|
+
code,
|
|
385
|
+
rateLimitInfo,
|
|
386
|
+
details,
|
|
387
|
+
requestId
|
|
388
|
+
);
|
|
382
389
|
}
|
|
383
390
|
default:
|
|
384
391
|
if (response.status >= 500) {
|
|
385
|
-
return new ServerError(
|
|
392
|
+
return new ServerError(
|
|
393
|
+
message,
|
|
394
|
+
response.status,
|
|
395
|
+
code,
|
|
396
|
+
details,
|
|
397
|
+
requestId
|
|
398
|
+
);
|
|
386
399
|
}
|
|
387
|
-
return new SpooledError(
|
|
400
|
+
return new SpooledError(
|
|
401
|
+
message,
|
|
402
|
+
response.status,
|
|
403
|
+
code,
|
|
404
|
+
details,
|
|
405
|
+
requestId
|
|
406
|
+
);
|
|
388
407
|
}
|
|
389
408
|
}
|
|
390
409
|
function isSpooledError(error) {
|
|
@@ -642,7 +661,9 @@ var HttpClient = class {
|
|
|
642
661
|
if (externalSignal.aborted) {
|
|
643
662
|
controller.abort();
|
|
644
663
|
} else {
|
|
645
|
-
externalSignal.addEventListener("abort", () => controller.abort(), {
|
|
664
|
+
externalSignal.addEventListener("abort", () => controller.abort(), {
|
|
665
|
+
once: true
|
|
666
|
+
});
|
|
646
667
|
}
|
|
647
668
|
}
|
|
648
669
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -657,7 +678,10 @@ var HttpClient = class {
|
|
|
657
678
|
if (externalSignal?.aborted) {
|
|
658
679
|
throw error;
|
|
659
680
|
}
|
|
660
|
-
throw new TimeoutError(
|
|
681
|
+
throw new TimeoutError(
|
|
682
|
+
`Request timed out after ${timeoutMs}ms`,
|
|
683
|
+
timeoutMs
|
|
684
|
+
);
|
|
661
685
|
}
|
|
662
686
|
throw error;
|
|
663
687
|
} finally {
|
|
@@ -686,13 +710,21 @@ var HttpClient = class {
|
|
|
686
710
|
this.debug?.(`${method} ${url}`, { timeout, hasBody: !!options.body });
|
|
687
711
|
let response;
|
|
688
712
|
try {
|
|
689
|
-
response = await this.fetchWithTimeout(
|
|
713
|
+
response = await this.fetchWithTimeout(
|
|
714
|
+
url,
|
|
715
|
+
init,
|
|
716
|
+
timeout,
|
|
717
|
+
options.signal
|
|
718
|
+
);
|
|
690
719
|
} catch (error) {
|
|
691
720
|
if (error instanceof TimeoutError || error instanceof SpooledError) {
|
|
692
721
|
throw error;
|
|
693
722
|
}
|
|
694
723
|
const cause = error instanceof Error ? error : void 0;
|
|
695
|
-
throw new NetworkError(
|
|
724
|
+
throw new NetworkError(
|
|
725
|
+
`Network request failed: ${cause?.message ?? "Unknown error"}`,
|
|
726
|
+
cause
|
|
727
|
+
);
|
|
696
728
|
}
|
|
697
729
|
this.debug?.(`Response: ${response.status}`, { url });
|
|
698
730
|
if (!response.ok) {
|
|
@@ -739,7 +771,9 @@ var HttpClient = class {
|
|
|
739
771
|
const url = this.buildUrl(path, options.params, options.skipApiPrefix);
|
|
740
772
|
const method = options.method ?? "GET";
|
|
741
773
|
const execute = async () => {
|
|
742
|
-
return this.circuitBreaker.execute(
|
|
774
|
+
return this.circuitBreaker.execute(
|
|
775
|
+
() => this.executeRequest(url, options)
|
|
776
|
+
);
|
|
743
777
|
};
|
|
744
778
|
if (options.skipRetry) {
|
|
745
779
|
return execute();
|
|
@@ -748,7 +782,9 @@ var HttpClient = class {
|
|
|
748
782
|
config: this.resolveRetryConfig(method, options),
|
|
749
783
|
signal: options.signal,
|
|
750
784
|
onRetry: (attempt, error, delayMs) => {
|
|
751
|
-
this.debug?.(`Retry attempt ${attempt} after ${delayMs}ms`, {
|
|
785
|
+
this.debug?.(`Retry attempt ${attempt} after ${delayMs}ms`, {
|
|
786
|
+
error: error.message
|
|
787
|
+
});
|
|
752
788
|
}
|
|
753
789
|
});
|
|
754
790
|
}
|
|
@@ -760,7 +796,9 @@ var HttpClient = class {
|
|
|
760
796
|
if (!options.headers) {
|
|
761
797
|
return false;
|
|
762
798
|
}
|
|
763
|
-
return Object.keys(options.headers).some(
|
|
799
|
+
return Object.keys(options.headers).some(
|
|
800
|
+
(key) => key.toLowerCase() === "idempotency-key"
|
|
801
|
+
);
|
|
764
802
|
}
|
|
765
803
|
/**
|
|
766
804
|
* Resolve the retry configuration for a request.
|
|
@@ -798,28 +836,43 @@ var HttpClient = class {
|
|
|
798
836
|
* Make a POST request
|
|
799
837
|
*/
|
|
800
838
|
async post(path, body, options) {
|
|
801
|
-
const response = await this.request(path, {
|
|
839
|
+
const response = await this.request(path, {
|
|
840
|
+
...options,
|
|
841
|
+
method: "POST",
|
|
842
|
+
body
|
|
843
|
+
});
|
|
802
844
|
return response.data;
|
|
803
845
|
}
|
|
804
846
|
/**
|
|
805
847
|
* Make a PUT request
|
|
806
848
|
*/
|
|
807
849
|
async put(path, body, options) {
|
|
808
|
-
const response = await this.request(path, {
|
|
850
|
+
const response = await this.request(path, {
|
|
851
|
+
...options,
|
|
852
|
+
method: "PUT",
|
|
853
|
+
body
|
|
854
|
+
});
|
|
809
855
|
return response.data;
|
|
810
856
|
}
|
|
811
857
|
/**
|
|
812
858
|
* Make a PATCH request
|
|
813
859
|
*/
|
|
814
860
|
async patch(path, body, options) {
|
|
815
|
-
const response = await this.request(path, {
|
|
861
|
+
const response = await this.request(path, {
|
|
862
|
+
...options,
|
|
863
|
+
method: "PATCH",
|
|
864
|
+
body
|
|
865
|
+
});
|
|
816
866
|
return response.data;
|
|
817
867
|
}
|
|
818
868
|
/**
|
|
819
869
|
* Make a DELETE request
|
|
820
870
|
*/
|
|
821
871
|
async delete(path, options) {
|
|
822
|
-
const response = await this.request(path, {
|
|
872
|
+
const response = await this.request(path, {
|
|
873
|
+
...options,
|
|
874
|
+
method: "DELETE"
|
|
875
|
+
});
|
|
823
876
|
return response.data;
|
|
824
877
|
}
|
|
825
878
|
};
|
|
@@ -1013,7 +1066,10 @@ var AuthResource = class {
|
|
|
1013
1066
|
*/
|
|
1014
1067
|
async logout(refreshToken) {
|
|
1015
1068
|
const token = refreshToken ?? this.getRefreshToken?.();
|
|
1016
|
-
await this.http.post(
|
|
1069
|
+
await this.http.post(
|
|
1070
|
+
"/auth/logout",
|
|
1071
|
+
token ? { refreshToken: token } : void 0
|
|
1072
|
+
);
|
|
1017
1073
|
}
|
|
1018
1074
|
/**
|
|
1019
1075
|
* Get current user/session info
|
|
@@ -1031,7 +1087,10 @@ var AuthResource = class {
|
|
|
1031
1087
|
* Start email-based login flow (sends magic link)
|
|
1032
1088
|
*/
|
|
1033
1089
|
async startEmailLogin(email) {
|
|
1034
|
-
return this.http.post(
|
|
1090
|
+
return this.http.post(
|
|
1091
|
+
"/auth/email/start",
|
|
1092
|
+
{ email }
|
|
1093
|
+
);
|
|
1035
1094
|
}
|
|
1036
1095
|
/**
|
|
1037
1096
|
* Check if an email address exists in the system
|
|
@@ -1072,7 +1131,9 @@ var JobsResource = class {
|
|
|
1072
1131
|
* List jobs with optional filtering
|
|
1073
1132
|
*/
|
|
1074
1133
|
async list(params) {
|
|
1075
|
-
return this.http.get("/jobs", {
|
|
1134
|
+
return this.http.get("/jobs", {
|
|
1135
|
+
params
|
|
1136
|
+
});
|
|
1076
1137
|
}
|
|
1077
1138
|
/**
|
|
1078
1139
|
* Get a job by ID
|
|
@@ -1096,7 +1157,9 @@ var JobsResource = class {
|
|
|
1096
1157
|
* Boost job priority
|
|
1097
1158
|
*/
|
|
1098
1159
|
async boostPriority(id, priority) {
|
|
1099
|
-
return this.http.put(`/jobs/${id}/priority`, {
|
|
1160
|
+
return this.http.put(`/jobs/${id}/priority`, {
|
|
1161
|
+
priority
|
|
1162
|
+
});
|
|
1100
1163
|
}
|
|
1101
1164
|
/**
|
|
1102
1165
|
* Get job statistics
|
|
@@ -1141,17 +1204,25 @@ var JobsResource = class {
|
|
|
1141
1204
|
* Fail a job (worker nack)
|
|
1142
1205
|
*/
|
|
1143
1206
|
async fail(id, params) {
|
|
1144
|
-
return this.http.post(
|
|
1207
|
+
return this.http.post(
|
|
1208
|
+
`/jobs/${id}/fail`,
|
|
1209
|
+
params
|
|
1210
|
+
);
|
|
1145
1211
|
}
|
|
1146
1212
|
/**
|
|
1147
1213
|
* Extend job lease (heartbeat)
|
|
1148
1214
|
*/
|
|
1149
1215
|
async heartbeat(id, params) {
|
|
1150
|
-
return this.http.post(
|
|
1216
|
+
return this.http.post(
|
|
1217
|
+
`/jobs/${id}/heartbeat`,
|
|
1218
|
+
params
|
|
1219
|
+
);
|
|
1151
1220
|
}
|
|
1152
1221
|
// DLQ operations (private implementations)
|
|
1153
1222
|
async listDlq(params) {
|
|
1154
|
-
return this.http.get("/jobs/dlq", {
|
|
1223
|
+
return this.http.get("/jobs/dlq", {
|
|
1224
|
+
params
|
|
1225
|
+
});
|
|
1155
1226
|
}
|
|
1156
1227
|
async retryDlq(params) {
|
|
1157
1228
|
return this.http.post("/jobs/dlq/retry", params);
|
|
@@ -1182,13 +1253,18 @@ var QueuesResource = class {
|
|
|
1182
1253
|
* Update queue configuration
|
|
1183
1254
|
*/
|
|
1184
1255
|
async updateConfig(name, params) {
|
|
1185
|
-
return this.http.put(
|
|
1256
|
+
return this.http.put(
|
|
1257
|
+
`/queues/${encodeURIComponent(name)}/config`,
|
|
1258
|
+
params
|
|
1259
|
+
);
|
|
1186
1260
|
}
|
|
1187
1261
|
/**
|
|
1188
1262
|
* Get queue statistics
|
|
1189
1263
|
*/
|
|
1190
1264
|
async getStats(name) {
|
|
1191
|
-
return this.http.get(
|
|
1265
|
+
return this.http.get(
|
|
1266
|
+
`/queues/${encodeURIComponent(name)}/stats`
|
|
1267
|
+
);
|
|
1192
1268
|
}
|
|
1193
1269
|
/**
|
|
1194
1270
|
* Pause a queue
|
|
@@ -1203,7 +1279,9 @@ var QueuesResource = class {
|
|
|
1203
1279
|
* Resume a paused queue
|
|
1204
1280
|
*/
|
|
1205
1281
|
async resume(name) {
|
|
1206
|
-
return this.http.post(
|
|
1282
|
+
return this.http.post(
|
|
1283
|
+
`/queues/${encodeURIComponent(name)}/resume`
|
|
1284
|
+
);
|
|
1207
1285
|
}
|
|
1208
1286
|
/**
|
|
1209
1287
|
* Delete a queue configuration
|
|
@@ -1259,7 +1337,9 @@ var SchedulesResource = class {
|
|
|
1259
1337
|
* List all schedules
|
|
1260
1338
|
*/
|
|
1261
1339
|
async list(params) {
|
|
1262
|
-
return this.http.get("/schedules", {
|
|
1340
|
+
return this.http.get("/schedules", {
|
|
1341
|
+
params
|
|
1342
|
+
});
|
|
1263
1343
|
}
|
|
1264
1344
|
/**
|
|
1265
1345
|
* Create a new schedule
|
|
@@ -1331,7 +1411,9 @@ var WorkflowsResource = class {
|
|
|
1331
1411
|
* List all workflows
|
|
1332
1412
|
*/
|
|
1333
1413
|
async list(params) {
|
|
1334
|
-
return this.http.get("/workflows", {
|
|
1414
|
+
return this.http.get("/workflows", {
|
|
1415
|
+
params
|
|
1416
|
+
});
|
|
1335
1417
|
}
|
|
1336
1418
|
/**
|
|
1337
1419
|
* Create a new workflow
|
|
@@ -1368,13 +1450,18 @@ var WorkflowsResource = class {
|
|
|
1368
1450
|
return this.http.get(`/workflows/${workflowId}/jobs/${jobId}`);
|
|
1369
1451
|
}
|
|
1370
1452
|
async getWorkflowJobsStatus(workflowId) {
|
|
1371
|
-
return this.http.get(
|
|
1453
|
+
return this.http.get(
|
|
1454
|
+
`/workflows/${workflowId}/jobs/status`
|
|
1455
|
+
);
|
|
1372
1456
|
}
|
|
1373
1457
|
async getJobDependencies(jobId) {
|
|
1374
1458
|
return this.http.get(`/jobs/${jobId}/dependencies`);
|
|
1375
1459
|
}
|
|
1376
1460
|
async addJobDependencies(jobId, params) {
|
|
1377
|
-
return this.http.post(
|
|
1461
|
+
return this.http.post(
|
|
1462
|
+
`/jobs/${jobId}/dependencies`,
|
|
1463
|
+
params
|
|
1464
|
+
);
|
|
1378
1465
|
}
|
|
1379
1466
|
};
|
|
1380
1467
|
|
|
@@ -1423,7 +1510,9 @@ var WebhooksResource = class {
|
|
|
1423
1510
|
* Get webhook delivery history
|
|
1424
1511
|
*/
|
|
1425
1512
|
async getDeliveries(id) {
|
|
1426
|
-
return this.http.get(
|
|
1513
|
+
return this.http.get(
|
|
1514
|
+
`/outgoing-webhooks/${id}/deliveries`
|
|
1515
|
+
);
|
|
1427
1516
|
}
|
|
1428
1517
|
/**
|
|
1429
1518
|
* Retry a specific webhook delivery
|
|
@@ -1531,7 +1620,9 @@ var OrganizationsResource = class {
|
|
|
1531
1620
|
* Generate a unique slug from an organization name
|
|
1532
1621
|
*/
|
|
1533
1622
|
async generateSlug(name) {
|
|
1534
|
-
return this.http.post("/organizations/generate-slug", {
|
|
1623
|
+
return this.http.post("/organizations/generate-slug", {
|
|
1624
|
+
name
|
|
1625
|
+
});
|
|
1535
1626
|
}
|
|
1536
1627
|
/**
|
|
1537
1628
|
* Get the webhook token for the current organization.
|
|
@@ -1561,7 +1652,9 @@ var OrganizationsResource = class {
|
|
|
1561
1652
|
* ```
|
|
1562
1653
|
*/
|
|
1563
1654
|
async regenerateWebhookToken() {
|
|
1564
|
-
return this.http.post(
|
|
1655
|
+
return this.http.post(
|
|
1656
|
+
"/organizations/webhook-token/regenerate"
|
|
1657
|
+
);
|
|
1565
1658
|
}
|
|
1566
1659
|
/**
|
|
1567
1660
|
* Clear/delete the webhook token for the current organization.
|
|
@@ -1598,7 +1691,10 @@ var BillingResource = class {
|
|
|
1598
1691
|
* POST /api/v1/billing/portal
|
|
1599
1692
|
*/
|
|
1600
1693
|
async createPortal(params) {
|
|
1601
|
-
return this.http.post(
|
|
1694
|
+
return this.http.post(
|
|
1695
|
+
"/billing/portal",
|
|
1696
|
+
params
|
|
1697
|
+
);
|
|
1602
1698
|
}
|
|
1603
1699
|
};
|
|
1604
1700
|
|
|
@@ -1693,7 +1789,9 @@ var AdminResource = class {
|
|
|
1693
1789
|
}
|
|
1694
1790
|
headers() {
|
|
1695
1791
|
if (!this.adminKey) {
|
|
1696
|
-
throw new AuthenticationError(
|
|
1792
|
+
throw new AuthenticationError(
|
|
1793
|
+
"Admin key is required for admin endpoints. Provide `adminKey` in SpooledClient config."
|
|
1794
|
+
);
|
|
1697
1795
|
}
|
|
1698
1796
|
return { "X-Admin-Key": this.adminKey };
|
|
1699
1797
|
}
|
|
@@ -1714,15 +1812,22 @@ var AdminResource = class {
|
|
|
1714
1812
|
}
|
|
1715
1813
|
/** POST /api/v1/admin/organizations */
|
|
1716
1814
|
async createOrganization(params) {
|
|
1717
|
-
return this.http.post(
|
|
1718
|
-
|
|
1719
|
-
|
|
1815
|
+
return this.http.post(
|
|
1816
|
+
"/admin/organizations",
|
|
1817
|
+
params,
|
|
1818
|
+
{
|
|
1819
|
+
headers: this.headers()
|
|
1820
|
+
}
|
|
1821
|
+
);
|
|
1720
1822
|
}
|
|
1721
1823
|
/** GET /api/v1/admin/organizations/{id} */
|
|
1722
1824
|
async getOrganization(id) {
|
|
1723
|
-
return this.http.get(
|
|
1724
|
-
|
|
1725
|
-
|
|
1825
|
+
return this.http.get(
|
|
1826
|
+
`/admin/organizations/${id}`,
|
|
1827
|
+
{
|
|
1828
|
+
headers: this.headers()
|
|
1829
|
+
}
|
|
1830
|
+
);
|
|
1726
1831
|
}
|
|
1727
1832
|
/** PATCH /api/v1/admin/organizations/{id} */
|
|
1728
1833
|
async updateOrganization(id, params) {
|
|
@@ -1740,15 +1845,23 @@ var AdminResource = class {
|
|
|
1740
1845
|
}
|
|
1741
1846
|
/** POST /api/v1/admin/organizations/{id}/api-keys */
|
|
1742
1847
|
async createApiKey(orgId, params) {
|
|
1743
|
-
return this.http.post(
|
|
1744
|
-
|
|
1745
|
-
|
|
1848
|
+
return this.http.post(
|
|
1849
|
+
`/admin/organizations/${orgId}/api-keys`,
|
|
1850
|
+
params,
|
|
1851
|
+
{
|
|
1852
|
+
headers: this.headers()
|
|
1853
|
+
}
|
|
1854
|
+
);
|
|
1746
1855
|
}
|
|
1747
1856
|
/** POST /api/v1/admin/organizations/{id}/reset-usage */
|
|
1748
1857
|
async resetUsage(orgId) {
|
|
1749
|
-
await this.http.post(
|
|
1750
|
-
|
|
1751
|
-
|
|
1858
|
+
await this.http.post(
|
|
1859
|
+
`/admin/organizations/${orgId}/reset-usage`,
|
|
1860
|
+
void 0,
|
|
1861
|
+
{
|
|
1862
|
+
headers: this.headers()
|
|
1863
|
+
}
|
|
1864
|
+
);
|
|
1752
1865
|
}
|
|
1753
1866
|
/** GET /api/v1/admin/stats */
|
|
1754
1867
|
async getStats() {
|
|
@@ -1794,7 +1907,9 @@ var WebhookIngestionResource = class {
|
|
|
1794
1907
|
const bytes = toBytes(body);
|
|
1795
1908
|
const signature = options.signature ?? (options.secret ? githubSignature(options.secret, bytes) : void 0);
|
|
1796
1909
|
if (!signature) {
|
|
1797
|
-
throw new ValidationError(
|
|
1910
|
+
throw new ValidationError(
|
|
1911
|
+
"GitHub webhook signature is required (provide `signature` or `secret`)"
|
|
1912
|
+
);
|
|
1798
1913
|
}
|
|
1799
1914
|
const headers = {
|
|
1800
1915
|
"Content-Type": "application/json",
|
|
@@ -1825,7 +1940,9 @@ var WebhookIngestionResource = class {
|
|
|
1825
1940
|
const timestamp = options.timestamp ?? Math.floor(Date.now() / 1e3);
|
|
1826
1941
|
const signature = options.signature ?? (options.secret ? stripeSignature(options.secret, bytes, timestamp) : void 0);
|
|
1827
1942
|
if (!signature) {
|
|
1828
|
-
throw new ValidationError(
|
|
1943
|
+
throw new ValidationError(
|
|
1944
|
+
"Stripe webhook signature is required (provide `signature` or `secret`)"
|
|
1945
|
+
);
|
|
1829
1946
|
}
|
|
1830
1947
|
const headers = {
|
|
1831
1948
|
"Content-Type": "application/json",
|
|
@@ -1962,14 +2079,20 @@ var WebSocketRealtimeClient = class {
|
|
|
1962
2079
|
resolve();
|
|
1963
2080
|
};
|
|
1964
2081
|
this.ws.onmessage = (event) => {
|
|
1965
|
-
this.handleMessage(
|
|
2082
|
+
this.handleMessage(
|
|
2083
|
+
typeof event.data === "string" ? event.data : String(event.data)
|
|
2084
|
+
);
|
|
1966
2085
|
};
|
|
1967
2086
|
this.ws.onclose = (event) => {
|
|
1968
2087
|
this.options.debug(`WebSocket closed: ${event.code} ${event.reason}`);
|
|
1969
2088
|
const wasConnecting = this.state === "connecting";
|
|
1970
2089
|
this.handleDisconnect();
|
|
1971
2090
|
if (wasConnecting) {
|
|
1972
|
-
reject(
|
|
2091
|
+
reject(
|
|
2092
|
+
new Error(
|
|
2093
|
+
`WebSocket connection failed: ${event.reason || "Unknown error"}`
|
|
2094
|
+
)
|
|
2095
|
+
);
|
|
1973
2096
|
}
|
|
1974
2097
|
};
|
|
1975
2098
|
this.ws.onerror = (event) => {
|
|
@@ -2124,7 +2247,9 @@ var WebSocketRealtimeClient = class {
|
|
|
2124
2247
|
this.options.maxReconnectDelay
|
|
2125
2248
|
);
|
|
2126
2249
|
const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);
|
|
2127
|
-
this.options.debug(
|
|
2250
|
+
this.options.debug(
|
|
2251
|
+
`Scheduling reconnect attempt ${this.reconnectAttempts} in ${delay}ms`
|
|
2252
|
+
);
|
|
2128
2253
|
this.reconnectTimer = setTimeout(async () => {
|
|
2129
2254
|
try {
|
|
2130
2255
|
await this.connect();
|
|
@@ -2177,11 +2302,13 @@ function isAuthFailureEvent(event) {
|
|
|
2177
2302
|
if (!event) {
|
|
2178
2303
|
return false;
|
|
2179
2304
|
}
|
|
2180
|
-
const
|
|
2181
|
-
if (
|
|
2305
|
+
const status2 = event.status ?? event.statusCode ?? event.error?.status;
|
|
2306
|
+
if (status2 === 401 || status2 === 403) {
|
|
2182
2307
|
return true;
|
|
2183
2308
|
}
|
|
2184
|
-
const text = String(
|
|
2309
|
+
const text = String(
|
|
2310
|
+
event.message ?? event.error?.message ?? event.reason ?? ""
|
|
2311
|
+
);
|
|
2185
2312
|
return /\b(401|403)\b/.test(text);
|
|
2186
2313
|
}
|
|
2187
2314
|
|
|
@@ -2244,7 +2371,9 @@ var SseRealtimeClient = class {
|
|
|
2244
2371
|
EventSourceImpl = mod.default || mod.EventSource || mod;
|
|
2245
2372
|
} catch {
|
|
2246
2373
|
this.setState("disconnected");
|
|
2247
|
-
throw new Error(
|
|
2374
|
+
throw new Error(
|
|
2375
|
+
"eventsource package is required for SSE in Node.js. Install it with: npm install eventsource"
|
|
2376
|
+
);
|
|
2248
2377
|
}
|
|
2249
2378
|
}
|
|
2250
2379
|
let token;
|
|
@@ -2413,7 +2542,9 @@ var SseRealtimeClient = class {
|
|
|
2413
2542
|
this.options.maxReconnectDelay
|
|
2414
2543
|
);
|
|
2415
2544
|
const delay = Math.floor(baseDelay + Math.random() * baseDelay * 0.25);
|
|
2416
|
-
this.options.debug(
|
|
2545
|
+
this.options.debug(
|
|
2546
|
+
`Scheduling SSE reconnect attempt ${this.reconnectAttempts} in ${delay}ms`
|
|
2547
|
+
);
|
|
2417
2548
|
this.reconnectTimer = setTimeout(async () => {
|
|
2418
2549
|
try {
|
|
2419
2550
|
await this.connect(this.filter || void 0);
|
|
@@ -2559,20 +2690,40 @@ var PROTO_LOADER_OPTIONS = {
|
|
|
2559
2690
|
// Support oneofs
|
|
2560
2691
|
};
|
|
2561
2692
|
var cachedDefinition = null;
|
|
2562
|
-
function
|
|
2693
|
+
function getModuleDir() {
|
|
2563
2694
|
if (typeof (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) !== "undefined") {
|
|
2564
|
-
|
|
2565
|
-
const __dirname2 = path.dirname(__filename);
|
|
2566
|
-
return path.join(__dirname2, "../../proto/spooled.proto");
|
|
2695
|
+
return path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
|
|
2567
2696
|
}
|
|
2568
|
-
return
|
|
2697
|
+
return __dirname;
|
|
2698
|
+
}
|
|
2699
|
+
function getProtoPath() {
|
|
2700
|
+
const moduleDir = getModuleDir();
|
|
2701
|
+
const candidates = [
|
|
2702
|
+
// Bundled ESM/CJS: dist/index.js → ../proto/spooled.proto
|
|
2703
|
+
path.join(moduleDir, "../proto/spooled.proto"),
|
|
2704
|
+
// Source / unbundled: src/grpc/loader.ts → ../../proto/spooled.proto
|
|
2705
|
+
path.join(moduleDir, "../../proto/spooled.proto"),
|
|
2706
|
+
// Extra safety if moduleDir is package root
|
|
2707
|
+
path.join(moduleDir, "proto/spooled.proto")
|
|
2708
|
+
];
|
|
2709
|
+
for (const candidate of candidates) {
|
|
2710
|
+
if (fs.existsSync(candidate)) {
|
|
2711
|
+
return candidate;
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
throw new Error(
|
|
2715
|
+
`Spooled gRPC proto not found. Tried: ${candidates.join(", ")}. Ensure the package's proto/spooled.proto is installed next to dist/.`
|
|
2716
|
+
);
|
|
2569
2717
|
}
|
|
2570
2718
|
function loadProtoDefinition() {
|
|
2571
2719
|
if (cachedDefinition) {
|
|
2572
2720
|
return cachedDefinition;
|
|
2573
2721
|
}
|
|
2574
2722
|
const protoPath = getProtoPath();
|
|
2575
|
-
const packageDefinition = protoLoader__namespace.loadSync(
|
|
2723
|
+
const packageDefinition = protoLoader__namespace.loadSync(
|
|
2724
|
+
protoPath,
|
|
2725
|
+
PROTO_LOADER_OPTIONS
|
|
2726
|
+
);
|
|
2576
2727
|
const grpcObject = grpc2__namespace.loadPackageDefinition(packageDefinition);
|
|
2577
2728
|
cachedDefinition = grpcObject;
|
|
2578
2729
|
return cachedDefinition;
|
|
@@ -2582,7 +2733,10 @@ async function loadProtoDefinitionAsync() {
|
|
|
2582
2733
|
return cachedDefinition;
|
|
2583
2734
|
}
|
|
2584
2735
|
const protoPath = getProtoPath();
|
|
2585
|
-
const packageDefinition = await protoLoader__namespace.load(
|
|
2736
|
+
const packageDefinition = await protoLoader__namespace.load(
|
|
2737
|
+
protoPath,
|
|
2738
|
+
PROTO_LOADER_OPTIONS
|
|
2739
|
+
);
|
|
2586
2740
|
const grpcObject = grpc2__namespace.loadPackageDefinition(packageDefinition);
|
|
2587
2741
|
cachedDefinition = grpcObject;
|
|
2588
2742
|
return cachedDefinition;
|
|
@@ -2599,7 +2753,11 @@ async function* asyncIterableFromStream(stream, options) {
|
|
|
2599
2753
|
stream.cancel();
|
|
2600
2754
|
});
|
|
2601
2755
|
}
|
|
2602
|
-
return yield* new AsyncIterableStream(stream, {
|
|
2756
|
+
return yield* new AsyncIterableStream(stream, {
|
|
2757
|
+
onConnected,
|
|
2758
|
+
onError,
|
|
2759
|
+
onEnd
|
|
2760
|
+
});
|
|
2603
2761
|
}
|
|
2604
2762
|
var AsyncIterableStream = class {
|
|
2605
2763
|
stream;
|
|
@@ -2628,8 +2786,8 @@ var AsyncIterableStream = class {
|
|
|
2628
2786
|
onEnd?.();
|
|
2629
2787
|
resolve?.();
|
|
2630
2788
|
});
|
|
2631
|
-
this.stream.on("status", (
|
|
2632
|
-
if (
|
|
2789
|
+
this.stream.on("status", (status2) => {
|
|
2790
|
+
if (status2.code === 0) {
|
|
2633
2791
|
onConnected?.();
|
|
2634
2792
|
}
|
|
2635
2793
|
});
|
|
@@ -2730,7 +2888,9 @@ function decodeStruct(value) {
|
|
|
2730
2888
|
return value;
|
|
2731
2889
|
}
|
|
2732
2890
|
const fields = value.fields ?? {};
|
|
2733
|
-
return Object.fromEntries(
|
|
2891
|
+
return Object.fromEntries(
|
|
2892
|
+
Object.entries(fields).map(([key, entry]) => [key, decodeValue(entry)])
|
|
2893
|
+
);
|
|
2734
2894
|
}
|
|
2735
2895
|
function decodeValue(value) {
|
|
2736
2896
|
if ("nullValue" in value) {
|
|
@@ -2779,7 +2939,10 @@ function encodeEnqueueRequest(params) {
|
|
|
2779
2939
|
return encoded;
|
|
2780
2940
|
}
|
|
2781
2941
|
function encodeCompleteRequest(params) {
|
|
2782
|
-
return {
|
|
2942
|
+
return {
|
|
2943
|
+
...params,
|
|
2944
|
+
result: encodeStruct(params.result)
|
|
2945
|
+
};
|
|
2783
2946
|
}
|
|
2784
2947
|
function decodeJob(job) {
|
|
2785
2948
|
return {
|
|
@@ -2788,17 +2951,60 @@ function decodeJob(job) {
|
|
|
2788
2951
|
result: decodeStruct(job.result)
|
|
2789
2952
|
};
|
|
2790
2953
|
}
|
|
2791
|
-
function promisify(client, method, request, metadata) {
|
|
2954
|
+
function promisify(client, method, request, metadata, timeoutMs) {
|
|
2792
2955
|
return new Promise((resolve, reject) => {
|
|
2793
|
-
|
|
2956
|
+
const callback = (error, response) => {
|
|
2794
2957
|
if (error) {
|
|
2795
|
-
reject(error);
|
|
2958
|
+
reject(mapGrpcError(error, timeoutMs));
|
|
2796
2959
|
} else {
|
|
2797
2960
|
resolve(response);
|
|
2798
2961
|
}
|
|
2799
|
-
}
|
|
2962
|
+
};
|
|
2963
|
+
method.call(
|
|
2964
|
+
client,
|
|
2965
|
+
request,
|
|
2966
|
+
metadata,
|
|
2967
|
+
createUnaryCallOptions(timeoutMs),
|
|
2968
|
+
callback
|
|
2969
|
+
);
|
|
2800
2970
|
});
|
|
2801
2971
|
}
|
|
2972
|
+
function createUnaryCallOptions(timeoutMs) {
|
|
2973
|
+
if (timeoutMs === void 0) {
|
|
2974
|
+
return {};
|
|
2975
|
+
}
|
|
2976
|
+
return { deadline: new Date(Date.now() + timeoutMs) };
|
|
2977
|
+
}
|
|
2978
|
+
function mapGrpcError(error, timeoutMs) {
|
|
2979
|
+
const message = error.details || error.message || "gRPC request failed";
|
|
2980
|
+
switch (error.code) {
|
|
2981
|
+
case grpc2__namespace.status.DEADLINE_EXCEEDED:
|
|
2982
|
+
return new TimeoutError(message, timeoutMs ?? 0);
|
|
2983
|
+
case grpc2__namespace.status.UNAUTHENTICATED:
|
|
2984
|
+
return new AuthenticationError(message, "AUTHENTICATION_FAILED");
|
|
2985
|
+
case grpc2__namespace.status.PERMISSION_DENIED:
|
|
2986
|
+
return new AuthorizationError(message, "ACCESS_DENIED");
|
|
2987
|
+
case grpc2__namespace.status.NOT_FOUND:
|
|
2988
|
+
return new NotFoundError(message, "NOT_FOUND");
|
|
2989
|
+
case grpc2__namespace.status.INVALID_ARGUMENT:
|
|
2990
|
+
case grpc2__namespace.status.OUT_OF_RANGE:
|
|
2991
|
+
return new ValidationError(message, "VALIDATION_ERROR");
|
|
2992
|
+
case grpc2__namespace.status.ALREADY_EXISTS:
|
|
2993
|
+
case grpc2__namespace.status.ABORTED:
|
|
2994
|
+
case grpc2__namespace.status.FAILED_PRECONDITION:
|
|
2995
|
+
return new ConflictError(message, "CONFLICT");
|
|
2996
|
+
case grpc2__namespace.status.RESOURCE_EXHAUSTED:
|
|
2997
|
+
return new RateLimitError(message, "RATE_LIMIT_EXCEEDED");
|
|
2998
|
+
case grpc2__namespace.status.UNAVAILABLE:
|
|
2999
|
+
case grpc2__namespace.status.CANCELLED:
|
|
3000
|
+
return new NetworkError(message, error);
|
|
3001
|
+
default:
|
|
3002
|
+
if (error.code >= grpc2__namespace.status.INTERNAL) {
|
|
3003
|
+
return new ServerError(message, 500, "GRPC_SERVER_ERROR");
|
|
3004
|
+
}
|
|
3005
|
+
return new ServerError(message, 500, "GRPC_ERROR");
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
2802
3008
|
function shouldUseTls(address, explicitTls) {
|
|
2803
3009
|
if (explicitTls !== void 0) {
|
|
2804
3010
|
return explicitTls;
|
|
@@ -2807,53 +3013,99 @@ function shouldUseTls(address, explicitTls) {
|
|
|
2807
3013
|
return host !== "localhost" && host !== "127.0.0.1" && !host.startsWith("[::1]");
|
|
2808
3014
|
}
|
|
2809
3015
|
var GrpcQueueOperations = class {
|
|
2810
|
-
constructor(client, metadata) {
|
|
3016
|
+
constructor(client, metadata, timeoutMs) {
|
|
2811
3017
|
this.client = client;
|
|
2812
3018
|
this.metadata = metadata;
|
|
3019
|
+
this.timeoutMs = timeoutMs;
|
|
2813
3020
|
}
|
|
2814
3021
|
/**
|
|
2815
3022
|
* Enqueue a new job
|
|
2816
3023
|
*/
|
|
2817
3024
|
async enqueue(params) {
|
|
2818
|
-
return promisify(
|
|
3025
|
+
return promisify(
|
|
3026
|
+
this.client,
|
|
3027
|
+
this.client.Enqueue,
|
|
3028
|
+
encodeEnqueueRequest(params),
|
|
3029
|
+
this.metadata,
|
|
3030
|
+
this.timeoutMs
|
|
3031
|
+
);
|
|
2819
3032
|
}
|
|
2820
3033
|
/**
|
|
2821
3034
|
* Dequeue a job (for workers)
|
|
2822
3035
|
*/
|
|
2823
3036
|
async dequeue(params) {
|
|
2824
|
-
const response = await promisify(
|
|
3037
|
+
const response = await promisify(
|
|
3038
|
+
this.client,
|
|
3039
|
+
this.client.Dequeue,
|
|
3040
|
+
params,
|
|
3041
|
+
this.metadata,
|
|
3042
|
+
this.timeoutMs
|
|
3043
|
+
);
|
|
2825
3044
|
return { ...response, jobs: response.jobs.map(decodeJob) };
|
|
2826
3045
|
}
|
|
2827
3046
|
/**
|
|
2828
3047
|
* Complete a job successfully
|
|
2829
3048
|
*/
|
|
2830
3049
|
async complete(params) {
|
|
2831
|
-
return promisify(
|
|
3050
|
+
return promisify(
|
|
3051
|
+
this.client,
|
|
3052
|
+
this.client.Complete,
|
|
3053
|
+
encodeCompleteRequest(params),
|
|
3054
|
+
this.metadata,
|
|
3055
|
+
this.timeoutMs
|
|
3056
|
+
);
|
|
2832
3057
|
}
|
|
2833
3058
|
/**
|
|
2834
3059
|
* Fail a job
|
|
2835
3060
|
*/
|
|
2836
3061
|
async fail(params) {
|
|
2837
|
-
return promisify(
|
|
3062
|
+
return promisify(
|
|
3063
|
+
this.client,
|
|
3064
|
+
this.client.Fail,
|
|
3065
|
+
params,
|
|
3066
|
+
this.metadata,
|
|
3067
|
+
this.timeoutMs
|
|
3068
|
+
);
|
|
2838
3069
|
}
|
|
2839
3070
|
/**
|
|
2840
3071
|
* Renew a job's lease
|
|
2841
3072
|
*/
|
|
2842
3073
|
async renewLease(params) {
|
|
2843
|
-
return promisify(
|
|
3074
|
+
return promisify(
|
|
3075
|
+
this.client,
|
|
3076
|
+
this.client.RenewLease,
|
|
3077
|
+
params,
|
|
3078
|
+
this.metadata,
|
|
3079
|
+
this.timeoutMs
|
|
3080
|
+
);
|
|
2844
3081
|
}
|
|
2845
3082
|
/**
|
|
2846
3083
|
* Get a job by ID
|
|
2847
3084
|
*/
|
|
2848
3085
|
async getJob(jobId) {
|
|
2849
|
-
const response = await promisify(
|
|
2850
|
-
|
|
3086
|
+
const response = await promisify(
|
|
3087
|
+
this.client,
|
|
3088
|
+
this.client.GetJob,
|
|
3089
|
+
{ jobId },
|
|
3090
|
+
this.metadata,
|
|
3091
|
+
this.timeoutMs
|
|
3092
|
+
);
|
|
3093
|
+
return {
|
|
3094
|
+
...response,
|
|
3095
|
+
job: response.job ? decodeJob(response.job) : response.job
|
|
3096
|
+
};
|
|
2851
3097
|
}
|
|
2852
3098
|
/**
|
|
2853
3099
|
* Get queue statistics
|
|
2854
3100
|
*/
|
|
2855
3101
|
async getQueueStats(queueName) {
|
|
2856
|
-
return promisify(
|
|
3102
|
+
return promisify(
|
|
3103
|
+
this.client,
|
|
3104
|
+
this.client.GetQueueStats,
|
|
3105
|
+
{ queueName },
|
|
3106
|
+
this.metadata,
|
|
3107
|
+
this.timeoutMs
|
|
3108
|
+
);
|
|
2857
3109
|
}
|
|
2858
3110
|
/**
|
|
2859
3111
|
* Stream jobs from a queue (server-side streaming)
|
|
@@ -2901,27 +3153,46 @@ var GrpcQueueOperations = class {
|
|
|
2901
3153
|
}
|
|
2902
3154
|
};
|
|
2903
3155
|
var GrpcWorkerOperations = class {
|
|
2904
|
-
constructor(client, metadata) {
|
|
3156
|
+
constructor(client, metadata, timeoutMs) {
|
|
2905
3157
|
this.client = client;
|
|
2906
3158
|
this.metadata = metadata;
|
|
3159
|
+
this.timeoutMs = timeoutMs;
|
|
2907
3160
|
}
|
|
2908
3161
|
/**
|
|
2909
3162
|
* Register a new worker
|
|
2910
3163
|
*/
|
|
2911
3164
|
async register(params) {
|
|
2912
|
-
return promisify(
|
|
3165
|
+
return promisify(
|
|
3166
|
+
this.client,
|
|
3167
|
+
this.client.Register,
|
|
3168
|
+
params,
|
|
3169
|
+
this.metadata,
|
|
3170
|
+
this.timeoutMs
|
|
3171
|
+
);
|
|
2913
3172
|
}
|
|
2914
3173
|
/**
|
|
2915
3174
|
* Send heartbeat
|
|
2916
3175
|
*/
|
|
2917
3176
|
async heartbeat(params) {
|
|
2918
|
-
return promisify(
|
|
3177
|
+
return promisify(
|
|
3178
|
+
this.client,
|
|
3179
|
+
this.client.Heartbeat,
|
|
3180
|
+
params,
|
|
3181
|
+
this.metadata,
|
|
3182
|
+
this.timeoutMs
|
|
3183
|
+
);
|
|
2919
3184
|
}
|
|
2920
3185
|
/**
|
|
2921
3186
|
* Deregister a worker
|
|
2922
3187
|
*/
|
|
2923
3188
|
async deregister(workerId) {
|
|
2924
|
-
return promisify(
|
|
3189
|
+
return promisify(
|
|
3190
|
+
this.client,
|
|
3191
|
+
this.client.Deregister,
|
|
3192
|
+
{ workerId },
|
|
3193
|
+
this.metadata,
|
|
3194
|
+
this.timeoutMs
|
|
3195
|
+
);
|
|
2925
3196
|
}
|
|
2926
3197
|
};
|
|
2927
3198
|
var SpooledGrpcClient = class {
|
|
@@ -2933,7 +3204,7 @@ var SpooledGrpcClient = class {
|
|
|
2933
3204
|
/** Worker operations */
|
|
2934
3205
|
workers;
|
|
2935
3206
|
constructor(options) {
|
|
2936
|
-
const { address, apiKey, useTls, credentials: credentials2, channelOptions } = options;
|
|
3207
|
+
const { address, apiKey, useTls, credentials: credentials2, channelOptions, timeout } = options;
|
|
2937
3208
|
const creds = credentials2 ?? (shouldUseTls(address, useTls) ? grpc2__namespace.credentials.createSsl() : grpc2__namespace.credentials.createInsecure());
|
|
2938
3209
|
this.metadata = new grpc2__namespace.Metadata();
|
|
2939
3210
|
this.metadata.add("x-api-key", apiKey);
|
|
@@ -2948,8 +3219,16 @@ var SpooledGrpcClient = class {
|
|
|
2948
3219
|
creds,
|
|
2949
3220
|
channelOptions
|
|
2950
3221
|
);
|
|
2951
|
-
this.queue = new GrpcQueueOperations(
|
|
2952
|
-
|
|
3222
|
+
this.queue = new GrpcQueueOperations(
|
|
3223
|
+
this.queueClient,
|
|
3224
|
+
this.metadata,
|
|
3225
|
+
timeout
|
|
3226
|
+
);
|
|
3227
|
+
this.workers = new GrpcWorkerOperations(
|
|
3228
|
+
this.workerClient,
|
|
3229
|
+
this.metadata,
|
|
3230
|
+
timeout
|
|
3231
|
+
);
|
|
2953
3232
|
}
|
|
2954
3233
|
/**
|
|
2955
3234
|
* Close all gRPC connections
|
|
@@ -3098,7 +3377,8 @@ var SpooledClient = class _SpooledClient {
|
|
|
3098
3377
|
}
|
|
3099
3378
|
this._grpc = new SpooledGrpcClient({
|
|
3100
3379
|
address: grpcAddress,
|
|
3101
|
-
apiKey
|
|
3380
|
+
apiKey,
|
|
3381
|
+
timeout: this.config.timeout
|
|
3102
3382
|
});
|
|
3103
3383
|
}
|
|
3104
3384
|
return this._grpc;
|
|
@@ -3165,7 +3445,9 @@ var SpooledClient = class _SpooledClient {
|
|
|
3165
3445
|
}
|
|
3166
3446
|
return this.loginForJwt();
|
|
3167
3447
|
}
|
|
3168
|
-
throw new AuthenticationError(
|
|
3448
|
+
throw new AuthenticationError(
|
|
3449
|
+
"No authentication method available for realtime connection"
|
|
3450
|
+
);
|
|
3169
3451
|
}
|
|
3170
3452
|
/**
|
|
3171
3453
|
* Exchange the API key for a JWT via /auth/login and cache the result.
|
|
@@ -3462,7 +3744,10 @@ var SpooledWorker = class {
|
|
|
3462
3744
|
this.sendWorkerHeartbeat();
|
|
3463
3745
|
}, heartbeatInterval);
|
|
3464
3746
|
this.state = "running";
|
|
3465
|
-
this.emit("started", {
|
|
3747
|
+
this.emit("started", {
|
|
3748
|
+
workerId: this.workerId,
|
|
3749
|
+
queueName: this.options.queueName
|
|
3750
|
+
});
|
|
3466
3751
|
this.schedulePoll();
|
|
3467
3752
|
} catch (error) {
|
|
3468
3753
|
this.state = "error";
|
|
@@ -3498,14 +3783,18 @@ var SpooledWorker = class {
|
|
|
3498
3783
|
active.abortController.abort();
|
|
3499
3784
|
}
|
|
3500
3785
|
if (this.activeJobs.size > 0) {
|
|
3501
|
-
this.debug(
|
|
3786
|
+
this.debug(
|
|
3787
|
+
`Waiting for ${this.activeJobs.size} active jobs to complete...`
|
|
3788
|
+
);
|
|
3502
3789
|
await Promise.race([
|
|
3503
3790
|
this.waitForActiveJobs(),
|
|
3504
3791
|
this.sleep(this.options.shutdownTimeout)
|
|
3505
3792
|
]);
|
|
3506
3793
|
const remaining = Array.from(this.activeJobs.values());
|
|
3507
3794
|
for (const active of remaining) {
|
|
3508
|
-
this.debug(
|
|
3795
|
+
this.debug(
|
|
3796
|
+
`Force-failing job ${active.job.id} due to shutdown timeout`
|
|
3797
|
+
);
|
|
3509
3798
|
await this.failJob(active.job, "Worker shutdown timeout");
|
|
3510
3799
|
this.cleanupJob(active);
|
|
3511
3800
|
}
|
|
@@ -3613,7 +3902,9 @@ var SpooledWorker = class {
|
|
|
3613
3902
|
retryCount: job.retryCount,
|
|
3614
3903
|
maxRetries: job.maxRetries,
|
|
3615
3904
|
signal,
|
|
3616
|
-
progress: async (
|
|
3905
|
+
progress: async (percent, message) => {
|
|
3906
|
+
const boundedPercent = Math.max(0, Math.min(100, percent));
|
|
3907
|
+
this.debug(`[${job.id}] progress ${boundedPercent}%`, message);
|
|
3617
3908
|
},
|
|
3618
3909
|
log: (level, message, meta) => {
|
|
3619
3910
|
this.debug(`[${job.id}] [${level}] ${message}`, meta);
|
|
@@ -3776,6 +4067,7 @@ exports.createPaginatedResponse = createPaginatedResponse;
|
|
|
3776
4067
|
exports.createProcessJobsStream = createProcessJobsStream;
|
|
3777
4068
|
exports.createRetryWrapper = createRetryWrapper;
|
|
3778
4069
|
exports.dateToTimestamp = dateToTimestamp;
|
|
4070
|
+
exports.getProtoPath = getProtoPath;
|
|
3779
4071
|
exports.isRetryableError = isRetryableError;
|
|
3780
4072
|
exports.isSpooledError = isSpooledError;
|
|
3781
4073
|
exports.loadProtoDefinition = loadProtoDefinition;
|