@signaliz/sdk 1.0.44 → 1.0.46
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 +4 -0
- package/dist/{chunk-Q4T2GUXD.mjs → chunk-4LXMT3S5.mjs} +73 -15
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +73 -15
- package/dist/index.mjs +1 -1
- package/dist/mcp-config.js +73 -15
- package/dist/mcp-config.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,6 +100,10 @@ const compactSignals = await signaliz.enrichCompanies(companies, {
|
|
|
100
100
|
});
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
+
Failed rows preserve `errorCode`, `retryEligible`, and `retryAfterSeconds`
|
|
104
|
+
when the REST API supplies them, including after automatic row retries are
|
|
105
|
+
exhausted.
|
|
106
|
+
|
|
103
107
|
For an ambiguous submission failure, retry with the same
|
|
104
108
|
`idempotencyKey` to recover the original job without duplicate work.
|
|
105
109
|
|
|
@@ -496,7 +496,11 @@ var Signaliz = class {
|
|
|
496
496
|
const params = companies[item.index];
|
|
497
497
|
const task = taskByIndex.get(item.index);
|
|
498
498
|
if (!item.success || !item.raw) {
|
|
499
|
-
results[item.index] =
|
|
499
|
+
results[item.index] = batchItemFailure(
|
|
500
|
+
item.index,
|
|
501
|
+
item.error || "Company Signal batch request failed",
|
|
502
|
+
item.raw ?? item
|
|
503
|
+
);
|
|
500
504
|
continue;
|
|
501
505
|
}
|
|
502
506
|
if (!isPendingSignalResponse(item.raw) || params.waitForResult === false) {
|
|
@@ -605,11 +609,11 @@ var Signaliz = class {
|
|
|
605
609
|
const chunk = chunks[chunkResult.index];
|
|
606
610
|
if (!chunkResult.success || !chunkResult.data) {
|
|
607
611
|
for (let index = 0; index < chunk.requests.length; index += 1) {
|
|
608
|
-
uniqueResults[chunk.offset + index] =
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
612
|
+
uniqueResults[chunk.offset + index] = batchItemFailure(
|
|
613
|
+
chunk.offset + index,
|
|
614
|
+
chunkResult.error || "Signal to Copy batch request failed",
|
|
615
|
+
chunkResult
|
|
616
|
+
);
|
|
613
617
|
}
|
|
614
618
|
continue;
|
|
615
619
|
}
|
|
@@ -631,7 +635,7 @@ var Signaliz = class {
|
|
|
631
635
|
const results = new Array(requests.length);
|
|
632
636
|
for (const row of rows) {
|
|
633
637
|
const index = Number(row.index);
|
|
634
|
-
results[index] = recoverableJobRowFailed(row) ?
|
|
638
|
+
results[index] = recoverableJobRowFailed(row) ? batchItemFailure(index, row.error || row.message || "Signal to Copy failed", row) : { index, success: true, data: normalizeSignalToCopyResult(row) };
|
|
635
639
|
}
|
|
636
640
|
return results;
|
|
637
641
|
}
|
|
@@ -705,9 +709,10 @@ var Signaliz = class {
|
|
|
705
709
|
if (seen.size !== requests.length) throw new Error(`${label} batch returned incomplete indexed results`);
|
|
706
710
|
return rows;
|
|
707
711
|
}
|
|
708
|
-
async runSignalCopyBatchChunk(requests, concurrency) {
|
|
712
|
+
async runSignalCopyBatchChunk(requests, concurrency, rowRateLimitAttempt = 0) {
|
|
709
713
|
const startedAt = Date.now();
|
|
710
714
|
const results = new Array(requests.length);
|
|
715
|
+
const rateLimited = [];
|
|
711
716
|
let pending = requests.map((params, index) => ({
|
|
712
717
|
index,
|
|
713
718
|
params,
|
|
@@ -727,7 +732,19 @@ var Signaliz = class {
|
|
|
727
732
|
const task = pending[index];
|
|
728
733
|
const item = data.results[index];
|
|
729
734
|
if (item.success === false) {
|
|
730
|
-
|
|
735
|
+
if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
|
|
736
|
+
index: task.index,
|
|
737
|
+
success: false,
|
|
738
|
+
raw: item
|
|
739
|
+
})) {
|
|
740
|
+
rateLimited.push({ index: task.index, params: task.params, raw: item });
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
743
|
+
results[task.index] = batchItemFailure(
|
|
744
|
+
task.index,
|
|
745
|
+
item.error || item.message || "Signal to Copy failed",
|
|
746
|
+
item
|
|
747
|
+
);
|
|
731
748
|
continue;
|
|
732
749
|
}
|
|
733
750
|
if (!isPendingSignalResponse(item)) {
|
|
@@ -765,6 +782,21 @@ var Signaliz = class {
|
|
|
765
782
|
pending = nextPending;
|
|
766
783
|
if (pending.length > 0) await sleep2(nextDelayMs);
|
|
767
784
|
}
|
|
785
|
+
if (rateLimited.length > 0) {
|
|
786
|
+
await sleep2(rowRateLimitDelayMs(rateLimited.map((item) => ({
|
|
787
|
+
index: item.index,
|
|
788
|
+
success: false,
|
|
789
|
+
raw: item.raw
|
|
790
|
+
}))));
|
|
791
|
+
const retried = await this.runSignalCopyBatchChunk(
|
|
792
|
+
rateLimited.map((item) => item.params),
|
|
793
|
+
concurrency,
|
|
794
|
+
rowRateLimitAttempt + 1
|
|
795
|
+
);
|
|
796
|
+
for (let index = 0; index < rateLimited.length; index += 1) {
|
|
797
|
+
results[rateLimited[index].index] = { ...retried[index], index: rateLimited[index].index };
|
|
798
|
+
}
|
|
799
|
+
}
|
|
768
800
|
return results;
|
|
769
801
|
}
|
|
770
802
|
async runCoreBatchRound(path, tasks, options, companyRecoverableBatch, rowRateLimitAttempt = 0) {
|
|
@@ -817,7 +849,10 @@ var Signaliz = class {
|
|
|
817
849
|
uniqueResults[chunk.offset + index] = {
|
|
818
850
|
index: chunk.tasks[index].index,
|
|
819
851
|
success: false,
|
|
820
|
-
error: chunkResult.error || `${path} batch request failed
|
|
852
|
+
error: chunkResult.error || `${path} batch request failed`,
|
|
853
|
+
errorCode: chunkResult.errorCode,
|
|
854
|
+
retryEligible: chunkResult.retryEligible,
|
|
855
|
+
retryAfterSeconds: chunkResult.retryAfterSeconds
|
|
821
856
|
};
|
|
822
857
|
}
|
|
823
858
|
continue;
|
|
@@ -883,6 +918,21 @@ function rowRateLimitDelayMs(items) {
|
|
|
883
918
|
});
|
|
884
919
|
return Math.max(1, Math.min(6e4, Math.max(...delays)));
|
|
885
920
|
}
|
|
921
|
+
function batchItemFailure(index, error, raw) {
|
|
922
|
+
const errorCode = String(raw?.error_code ?? raw?.code ?? raw?.errorCode ?? "").trim();
|
|
923
|
+
const retryAfterSeconds2 = Number(
|
|
924
|
+
raw?.retry_after_seconds ?? raw?.retry_after ?? raw?.retryAfterSeconds ?? (Number.isFinite(Number(raw?.retry_after_ms)) ? Number(raw?.retry_after_ms) / 1e3 : void 0)
|
|
925
|
+
);
|
|
926
|
+
const retryEligible = raw?.retry_eligible ?? raw?.retryEligible;
|
|
927
|
+
return {
|
|
928
|
+
index,
|
|
929
|
+
success: false,
|
|
930
|
+
error,
|
|
931
|
+
...errorCode ? { errorCode } : {},
|
|
932
|
+
...typeof retryEligible === "boolean" ? { retryEligible } : {},
|
|
933
|
+
...Number.isFinite(retryAfterSeconds2) && retryAfterSeconds2 >= 0 ? { retryAfterSeconds: retryAfterSeconds2 } : {}
|
|
934
|
+
};
|
|
935
|
+
}
|
|
886
936
|
function recoverableJobRowFailed(row) {
|
|
887
937
|
return row.success === false || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
|
|
888
938
|
}
|
|
@@ -1093,7 +1143,11 @@ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
|
|
|
1093
1143
|
const results = new Array(total);
|
|
1094
1144
|
for (const item of round) {
|
|
1095
1145
|
if (!item.success || !item.raw) {
|
|
1096
|
-
results[item.index] =
|
|
1146
|
+
results[item.index] = batchItemFailure(
|
|
1147
|
+
item.index,
|
|
1148
|
+
item.error || "Signaliz batch item failed",
|
|
1149
|
+
item.raw ?? item
|
|
1150
|
+
);
|
|
1097
1151
|
continue;
|
|
1098
1152
|
}
|
|
1099
1153
|
try {
|
|
@@ -1221,11 +1275,15 @@ async function runBatch(items, execute, options) {
|
|
|
1221
1275
|
try {
|
|
1222
1276
|
results[index] = { index, success: true, data: await execute(items[index]) };
|
|
1223
1277
|
} catch (error) {
|
|
1224
|
-
results[index] =
|
|
1278
|
+
results[index] = batchItemFailure(
|
|
1225
1279
|
index,
|
|
1226
|
-
|
|
1227
|
-
error
|
|
1228
|
-
|
|
1280
|
+
error instanceof Error ? error.message : String(error),
|
|
1281
|
+
error instanceof SignalizError ? {
|
|
1282
|
+
error_code: error.code,
|
|
1283
|
+
retry_eligible: error.isRetryable,
|
|
1284
|
+
retry_after_seconds: error.retryAfter
|
|
1285
|
+
} : void 0
|
|
1286
|
+
);
|
|
1229
1287
|
}
|
|
1230
1288
|
}
|
|
1231
1289
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -19,6 +19,12 @@ interface BatchItemResult<T> {
|
|
|
19
19
|
success: boolean;
|
|
20
20
|
data?: T;
|
|
21
21
|
error?: string;
|
|
22
|
+
/** Stable public error code for a failed row. */
|
|
23
|
+
errorCode?: string;
|
|
24
|
+
/** Whether retrying the failed row is safe. */
|
|
25
|
+
retryEligible?: boolean;
|
|
26
|
+
/** Server-provided delay before retrying the failed row. */
|
|
27
|
+
retryAfterSeconds?: number;
|
|
22
28
|
/** Zero-based input index containing the full result for this exact duplicate. */
|
|
23
29
|
duplicateOf?: number;
|
|
24
30
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,12 @@ interface BatchItemResult<T> {
|
|
|
19
19
|
success: boolean;
|
|
20
20
|
data?: T;
|
|
21
21
|
error?: string;
|
|
22
|
+
/** Stable public error code for a failed row. */
|
|
23
|
+
errorCode?: string;
|
|
24
|
+
/** Whether retrying the failed row is safe. */
|
|
25
|
+
retryEligible?: boolean;
|
|
26
|
+
/** Server-provided delay before retrying the failed row. */
|
|
27
|
+
retryAfterSeconds?: number;
|
|
22
28
|
/** Zero-based input index containing the full result for this exact duplicate. */
|
|
23
29
|
duplicateOf?: number;
|
|
24
30
|
}
|
package/dist/index.js
CHANGED
|
@@ -523,7 +523,11 @@ var Signaliz = class {
|
|
|
523
523
|
const params = companies[item.index];
|
|
524
524
|
const task = taskByIndex.get(item.index);
|
|
525
525
|
if (!item.success || !item.raw) {
|
|
526
|
-
results[item.index] =
|
|
526
|
+
results[item.index] = batchItemFailure(
|
|
527
|
+
item.index,
|
|
528
|
+
item.error || "Company Signal batch request failed",
|
|
529
|
+
item.raw ?? item
|
|
530
|
+
);
|
|
527
531
|
continue;
|
|
528
532
|
}
|
|
529
533
|
if (!isPendingSignalResponse(item.raw) || params.waitForResult === false) {
|
|
@@ -632,11 +636,11 @@ var Signaliz = class {
|
|
|
632
636
|
const chunk = chunks[chunkResult.index];
|
|
633
637
|
if (!chunkResult.success || !chunkResult.data) {
|
|
634
638
|
for (let index = 0; index < chunk.requests.length; index += 1) {
|
|
635
|
-
uniqueResults[chunk.offset + index] =
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
639
|
+
uniqueResults[chunk.offset + index] = batchItemFailure(
|
|
640
|
+
chunk.offset + index,
|
|
641
|
+
chunkResult.error || "Signal to Copy batch request failed",
|
|
642
|
+
chunkResult
|
|
643
|
+
);
|
|
640
644
|
}
|
|
641
645
|
continue;
|
|
642
646
|
}
|
|
@@ -658,7 +662,7 @@ var Signaliz = class {
|
|
|
658
662
|
const results = new Array(requests.length);
|
|
659
663
|
for (const row of rows) {
|
|
660
664
|
const index = Number(row.index);
|
|
661
|
-
results[index] = recoverableJobRowFailed(row) ?
|
|
665
|
+
results[index] = recoverableJobRowFailed(row) ? batchItemFailure(index, row.error || row.message || "Signal to Copy failed", row) : { index, success: true, data: normalizeSignalToCopyResult(row) };
|
|
662
666
|
}
|
|
663
667
|
return results;
|
|
664
668
|
}
|
|
@@ -732,9 +736,10 @@ var Signaliz = class {
|
|
|
732
736
|
if (seen.size !== requests.length) throw new Error(`${label} batch returned incomplete indexed results`);
|
|
733
737
|
return rows;
|
|
734
738
|
}
|
|
735
|
-
async runSignalCopyBatchChunk(requests, concurrency) {
|
|
739
|
+
async runSignalCopyBatchChunk(requests, concurrency, rowRateLimitAttempt = 0) {
|
|
736
740
|
const startedAt = Date.now();
|
|
737
741
|
const results = new Array(requests.length);
|
|
742
|
+
const rateLimited = [];
|
|
738
743
|
let pending = requests.map((params, index) => ({
|
|
739
744
|
index,
|
|
740
745
|
params,
|
|
@@ -754,7 +759,19 @@ var Signaliz = class {
|
|
|
754
759
|
const task = pending[index];
|
|
755
760
|
const item = data.results[index];
|
|
756
761
|
if (item.success === false) {
|
|
757
|
-
|
|
762
|
+
if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
|
|
763
|
+
index: task.index,
|
|
764
|
+
success: false,
|
|
765
|
+
raw: item
|
|
766
|
+
})) {
|
|
767
|
+
rateLimited.push({ index: task.index, params: task.params, raw: item });
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
770
|
+
results[task.index] = batchItemFailure(
|
|
771
|
+
task.index,
|
|
772
|
+
item.error || item.message || "Signal to Copy failed",
|
|
773
|
+
item
|
|
774
|
+
);
|
|
758
775
|
continue;
|
|
759
776
|
}
|
|
760
777
|
if (!isPendingSignalResponse(item)) {
|
|
@@ -792,6 +809,21 @@ var Signaliz = class {
|
|
|
792
809
|
pending = nextPending;
|
|
793
810
|
if (pending.length > 0) await sleep2(nextDelayMs);
|
|
794
811
|
}
|
|
812
|
+
if (rateLimited.length > 0) {
|
|
813
|
+
await sleep2(rowRateLimitDelayMs(rateLimited.map((item) => ({
|
|
814
|
+
index: item.index,
|
|
815
|
+
success: false,
|
|
816
|
+
raw: item.raw
|
|
817
|
+
}))));
|
|
818
|
+
const retried = await this.runSignalCopyBatchChunk(
|
|
819
|
+
rateLimited.map((item) => item.params),
|
|
820
|
+
concurrency,
|
|
821
|
+
rowRateLimitAttempt + 1
|
|
822
|
+
);
|
|
823
|
+
for (let index = 0; index < rateLimited.length; index += 1) {
|
|
824
|
+
results[rateLimited[index].index] = { ...retried[index], index: rateLimited[index].index };
|
|
825
|
+
}
|
|
826
|
+
}
|
|
795
827
|
return results;
|
|
796
828
|
}
|
|
797
829
|
async runCoreBatchRound(path, tasks, options, companyRecoverableBatch, rowRateLimitAttempt = 0) {
|
|
@@ -844,7 +876,10 @@ var Signaliz = class {
|
|
|
844
876
|
uniqueResults[chunk.offset + index] = {
|
|
845
877
|
index: chunk.tasks[index].index,
|
|
846
878
|
success: false,
|
|
847
|
-
error: chunkResult.error || `${path} batch request failed
|
|
879
|
+
error: chunkResult.error || `${path} batch request failed`,
|
|
880
|
+
errorCode: chunkResult.errorCode,
|
|
881
|
+
retryEligible: chunkResult.retryEligible,
|
|
882
|
+
retryAfterSeconds: chunkResult.retryAfterSeconds
|
|
848
883
|
};
|
|
849
884
|
}
|
|
850
885
|
continue;
|
|
@@ -910,6 +945,21 @@ function rowRateLimitDelayMs(items) {
|
|
|
910
945
|
});
|
|
911
946
|
return Math.max(1, Math.min(6e4, Math.max(...delays)));
|
|
912
947
|
}
|
|
948
|
+
function batchItemFailure(index, error, raw) {
|
|
949
|
+
const errorCode = String(raw?.error_code ?? raw?.code ?? raw?.errorCode ?? "").trim();
|
|
950
|
+
const retryAfterSeconds2 = Number(
|
|
951
|
+
raw?.retry_after_seconds ?? raw?.retry_after ?? raw?.retryAfterSeconds ?? (Number.isFinite(Number(raw?.retry_after_ms)) ? Number(raw?.retry_after_ms) / 1e3 : void 0)
|
|
952
|
+
);
|
|
953
|
+
const retryEligible = raw?.retry_eligible ?? raw?.retryEligible;
|
|
954
|
+
return {
|
|
955
|
+
index,
|
|
956
|
+
success: false,
|
|
957
|
+
error,
|
|
958
|
+
...errorCode ? { errorCode } : {},
|
|
959
|
+
...typeof retryEligible === "boolean" ? { retryEligible } : {},
|
|
960
|
+
...Number.isFinite(retryAfterSeconds2) && retryAfterSeconds2 >= 0 ? { retryAfterSeconds: retryAfterSeconds2 } : {}
|
|
961
|
+
};
|
|
962
|
+
}
|
|
913
963
|
function recoverableJobRowFailed(row) {
|
|
914
964
|
return row.success === false || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
|
|
915
965
|
}
|
|
@@ -1120,7 +1170,11 @@ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
|
|
|
1120
1170
|
const results = new Array(total);
|
|
1121
1171
|
for (const item of round) {
|
|
1122
1172
|
if (!item.success || !item.raw) {
|
|
1123
|
-
results[item.index] =
|
|
1173
|
+
results[item.index] = batchItemFailure(
|
|
1174
|
+
item.index,
|
|
1175
|
+
item.error || "Signaliz batch item failed",
|
|
1176
|
+
item.raw ?? item
|
|
1177
|
+
);
|
|
1124
1178
|
continue;
|
|
1125
1179
|
}
|
|
1126
1180
|
try {
|
|
@@ -1248,11 +1302,15 @@ async function runBatch(items, execute, options) {
|
|
|
1248
1302
|
try {
|
|
1249
1303
|
results[index] = { index, success: true, data: await execute(items[index]) };
|
|
1250
1304
|
} catch (error) {
|
|
1251
|
-
results[index] =
|
|
1305
|
+
results[index] = batchItemFailure(
|
|
1252
1306
|
index,
|
|
1253
|
-
|
|
1254
|
-
error
|
|
1255
|
-
|
|
1307
|
+
error instanceof Error ? error.message : String(error),
|
|
1308
|
+
error instanceof SignalizError ? {
|
|
1309
|
+
error_code: error.code,
|
|
1310
|
+
retry_eligible: error.isRetryable,
|
|
1311
|
+
retry_after_seconds: error.retryAfter
|
|
1312
|
+
} : void 0
|
|
1313
|
+
);
|
|
1256
1314
|
}
|
|
1257
1315
|
}
|
|
1258
1316
|
};
|
package/dist/index.mjs
CHANGED
package/dist/mcp-config.js
CHANGED
|
@@ -527,7 +527,11 @@ var Signaliz = class {
|
|
|
527
527
|
const params = companies[item.index];
|
|
528
528
|
const task = taskByIndex.get(item.index);
|
|
529
529
|
if (!item.success || !item.raw) {
|
|
530
|
-
results[item.index] =
|
|
530
|
+
results[item.index] = batchItemFailure(
|
|
531
|
+
item.index,
|
|
532
|
+
item.error || "Company Signal batch request failed",
|
|
533
|
+
item.raw ?? item
|
|
534
|
+
);
|
|
531
535
|
continue;
|
|
532
536
|
}
|
|
533
537
|
if (!isPendingSignalResponse(item.raw) || params.waitForResult === false) {
|
|
@@ -636,11 +640,11 @@ var Signaliz = class {
|
|
|
636
640
|
const chunk = chunks[chunkResult.index];
|
|
637
641
|
if (!chunkResult.success || !chunkResult.data) {
|
|
638
642
|
for (let index = 0; index < chunk.requests.length; index += 1) {
|
|
639
|
-
uniqueResults[chunk.offset + index] =
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
643
|
+
uniqueResults[chunk.offset + index] = batchItemFailure(
|
|
644
|
+
chunk.offset + index,
|
|
645
|
+
chunkResult.error || "Signal to Copy batch request failed",
|
|
646
|
+
chunkResult
|
|
647
|
+
);
|
|
644
648
|
}
|
|
645
649
|
continue;
|
|
646
650
|
}
|
|
@@ -662,7 +666,7 @@ var Signaliz = class {
|
|
|
662
666
|
const results = new Array(requests.length);
|
|
663
667
|
for (const row of rows) {
|
|
664
668
|
const index = Number(row.index);
|
|
665
|
-
results[index] = recoverableJobRowFailed(row) ?
|
|
669
|
+
results[index] = recoverableJobRowFailed(row) ? batchItemFailure(index, row.error || row.message || "Signal to Copy failed", row) : { index, success: true, data: normalizeSignalToCopyResult(row) };
|
|
666
670
|
}
|
|
667
671
|
return results;
|
|
668
672
|
}
|
|
@@ -736,9 +740,10 @@ var Signaliz = class {
|
|
|
736
740
|
if (seen.size !== requests.length) throw new Error(`${label} batch returned incomplete indexed results`);
|
|
737
741
|
return rows;
|
|
738
742
|
}
|
|
739
|
-
async runSignalCopyBatchChunk(requests, concurrency) {
|
|
743
|
+
async runSignalCopyBatchChunk(requests, concurrency, rowRateLimitAttempt = 0) {
|
|
740
744
|
const startedAt = Date.now();
|
|
741
745
|
const results = new Array(requests.length);
|
|
746
|
+
const rateLimited = [];
|
|
742
747
|
let pending = requests.map((params, index) => ({
|
|
743
748
|
index,
|
|
744
749
|
params,
|
|
@@ -758,7 +763,19 @@ var Signaliz = class {
|
|
|
758
763
|
const task = pending[index];
|
|
759
764
|
const item = data.results[index];
|
|
760
765
|
if (item.success === false) {
|
|
761
|
-
|
|
766
|
+
if (rowRateLimitAttempt < MAX_ROW_RATE_LIMIT_RETRIES && isRetryableRowRateLimit({
|
|
767
|
+
index: task.index,
|
|
768
|
+
success: false,
|
|
769
|
+
raw: item
|
|
770
|
+
})) {
|
|
771
|
+
rateLimited.push({ index: task.index, params: task.params, raw: item });
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
results[task.index] = batchItemFailure(
|
|
775
|
+
task.index,
|
|
776
|
+
item.error || item.message || "Signal to Copy failed",
|
|
777
|
+
item
|
|
778
|
+
);
|
|
762
779
|
continue;
|
|
763
780
|
}
|
|
764
781
|
if (!isPendingSignalResponse(item)) {
|
|
@@ -796,6 +813,21 @@ var Signaliz = class {
|
|
|
796
813
|
pending = nextPending;
|
|
797
814
|
if (pending.length > 0) await sleep2(nextDelayMs);
|
|
798
815
|
}
|
|
816
|
+
if (rateLimited.length > 0) {
|
|
817
|
+
await sleep2(rowRateLimitDelayMs(rateLimited.map((item) => ({
|
|
818
|
+
index: item.index,
|
|
819
|
+
success: false,
|
|
820
|
+
raw: item.raw
|
|
821
|
+
}))));
|
|
822
|
+
const retried = await this.runSignalCopyBatchChunk(
|
|
823
|
+
rateLimited.map((item) => item.params),
|
|
824
|
+
concurrency,
|
|
825
|
+
rowRateLimitAttempt + 1
|
|
826
|
+
);
|
|
827
|
+
for (let index = 0; index < rateLimited.length; index += 1) {
|
|
828
|
+
results[rateLimited[index].index] = { ...retried[index], index: rateLimited[index].index };
|
|
829
|
+
}
|
|
830
|
+
}
|
|
799
831
|
return results;
|
|
800
832
|
}
|
|
801
833
|
async runCoreBatchRound(path2, tasks, options, companyRecoverableBatch, rowRateLimitAttempt = 0) {
|
|
@@ -848,7 +880,10 @@ var Signaliz = class {
|
|
|
848
880
|
uniqueResults[chunk.offset + index] = {
|
|
849
881
|
index: chunk.tasks[index].index,
|
|
850
882
|
success: false,
|
|
851
|
-
error: chunkResult.error || `${path2} batch request failed
|
|
883
|
+
error: chunkResult.error || `${path2} batch request failed`,
|
|
884
|
+
errorCode: chunkResult.errorCode,
|
|
885
|
+
retryEligible: chunkResult.retryEligible,
|
|
886
|
+
retryAfterSeconds: chunkResult.retryAfterSeconds
|
|
852
887
|
};
|
|
853
888
|
}
|
|
854
889
|
continue;
|
|
@@ -914,6 +949,21 @@ function rowRateLimitDelayMs(items) {
|
|
|
914
949
|
});
|
|
915
950
|
return Math.max(1, Math.min(6e4, Math.max(...delays)));
|
|
916
951
|
}
|
|
952
|
+
function batchItemFailure(index, error, raw) {
|
|
953
|
+
const errorCode = String(raw?.error_code ?? raw?.code ?? raw?.errorCode ?? "").trim();
|
|
954
|
+
const retryAfterSeconds2 = Number(
|
|
955
|
+
raw?.retry_after_seconds ?? raw?.retry_after ?? raw?.retryAfterSeconds ?? (Number.isFinite(Number(raw?.retry_after_ms)) ? Number(raw?.retry_after_ms) / 1e3 : void 0)
|
|
956
|
+
);
|
|
957
|
+
const retryEligible = raw?.retry_eligible ?? raw?.retryEligible;
|
|
958
|
+
return {
|
|
959
|
+
index,
|
|
960
|
+
success: false,
|
|
961
|
+
error,
|
|
962
|
+
...errorCode ? { errorCode } : {},
|
|
963
|
+
...typeof retryEligible === "boolean" ? { retryEligible } : {},
|
|
964
|
+
...Number.isFinite(retryAfterSeconds2) && retryAfterSeconds2 >= 0 ? { retryAfterSeconds: retryAfterSeconds2 } : {}
|
|
965
|
+
};
|
|
966
|
+
}
|
|
917
967
|
function recoverableJobRowFailed(row) {
|
|
918
968
|
return row.success === false || ["failed", "skipped"].includes(String(row._status || "").toLowerCase());
|
|
919
969
|
}
|
|
@@ -1124,7 +1174,11 @@ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
|
|
|
1124
1174
|
const results = new Array(total);
|
|
1125
1175
|
for (const item of round) {
|
|
1126
1176
|
if (!item.success || !item.raw) {
|
|
1127
|
-
results[item.index] =
|
|
1177
|
+
results[item.index] = batchItemFailure(
|
|
1178
|
+
item.index,
|
|
1179
|
+
item.error || "Signaliz batch item failed",
|
|
1180
|
+
item.raw ?? item
|
|
1181
|
+
);
|
|
1128
1182
|
continue;
|
|
1129
1183
|
}
|
|
1130
1184
|
try {
|
|
@@ -1252,11 +1306,15 @@ async function runBatch(items, execute, options) {
|
|
|
1252
1306
|
try {
|
|
1253
1307
|
results[index] = { index, success: true, data: await execute(items[index]) };
|
|
1254
1308
|
} catch (error) {
|
|
1255
|
-
results[index] =
|
|
1309
|
+
results[index] = batchItemFailure(
|
|
1256
1310
|
index,
|
|
1257
|
-
|
|
1258
|
-
error
|
|
1259
|
-
|
|
1311
|
+
error instanceof Error ? error.message : String(error),
|
|
1312
|
+
error instanceof SignalizError ? {
|
|
1313
|
+
error_code: error.code,
|
|
1314
|
+
retry_eligible: error.isRetryable,
|
|
1315
|
+
retry_after_seconds: error.retryAfter
|
|
1316
|
+
} : void 0
|
|
1317
|
+
);
|
|
1260
1318
|
}
|
|
1261
1319
|
}
|
|
1262
1320
|
};
|
package/dist/mcp-config.mjs
CHANGED
package/package.json
CHANGED