@signaliz/sdk 1.0.36 → 1.0.38

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 CHANGED
@@ -70,6 +70,13 @@ const verifiedBatch = await signaliz.verifyEmails(emails, { concurrency: 20 });
70
70
  const foundBatch = await signaliz.findEmails(contacts, { concurrency: 20 });
71
71
  const signalBatch = await signaliz.enrichCompanies(companies, { concurrency: 5 });
72
72
  const copyBatch = await signaliz.createSignalCopyBatch(copyRequests, { concurrency: 5 });
73
+
74
+ // Keep one full result for exact repeats and return duplicateOf references for
75
+ // the rest. This is lossless and avoids multiplying evidence-rich payloads.
76
+ const compactSignals = await signaliz.enrichCompanies(companies, {
77
+ concurrency: 5,
78
+ compactDuplicates: true,
79
+ });
73
80
  ```
74
81
 
75
82
  For an ambiguous submission failure, retry with the same
@@ -81,7 +88,10 @@ callers never need an internal Trigger.dev status URL. The SDK follows the
81
88
  server's adaptive polling hints by default and still honors `pollIntervalMs`
82
89
  when a caller explicitly overrides the cadence.
83
90
  Exact duplicate tasks are single-flighted across each full batch without
84
- changing input order or result cardinality. Find Email and Verify Email batches
91
+ changing input order or result cardinality. Set `compactDuplicates: true` to
92
+ return repeated successful rows as `duplicateOf` references to the zero-based
93
+ canonical input index; the default remains expanded for compatibility. Find Email and Verify Email
94
+ batches
85
95
  larger than 25 use one cache-aware recoverable REST job with 500-row result
86
96
  pages. Uniform Company Signal Enrichment batches larger than 25 use one
87
97
  cache-aware recoverable REST job with 25-row result pages; heterogeneous,
@@ -22,16 +22,19 @@ function parseError(status, body) {
22
22
  details: body.error.details
23
23
  });
24
24
  }
25
+ const code = typeof body?.error_code === "string" && body.error_code.trim() ? body.error_code.trim() : `HTTP_${status}`;
25
26
  return new SignalizError({
26
- code: `HTTP_${status}`,
27
+ code,
27
28
  message: body?.message || body?.error || `Request failed with status ${status}`,
28
- errorType: mapErrorType(void 0, status)
29
+ errorType: mapErrorType(code, status),
30
+ details: body?.details || (body?.retry_eligible !== void 0 ? { retry_eligible: body.retry_eligible } : void 0)
29
31
  });
30
32
  }
31
33
  function mapErrorType(code, status) {
32
34
  if (code === "RATE_LIMITED" || status === 429) return "rate_limited";
33
35
  if (code === "VALIDATION_ERROR" || status === 400) return "validation";
34
36
  if (code === "NOT_FOUND" || status === 404) return "not_found";
37
+ if (code === "NO_SUPPORTED_SIGNAL") return "not_found";
35
38
  if (code === "AUTH_EXPIRED" || status === 401) return "auth_expired";
36
39
  if (code === "INSUFFICIENT_CREDITS" || status === 402) return "insufficient_credits";
37
40
  if (code === "TIMEOUT" || status === 504) return "timeout";
@@ -368,7 +371,8 @@ var Signaliz = class {
368
371
  params.length,
369
372
  startedAt,
370
373
  round,
371
- (item) => normalizeFindEmailResult(item.raw)
374
+ (item) => normalizeFindEmailResult(item.raw),
375
+ options
372
376
  );
373
377
  }
374
378
  async verifyEmail(email, options) {
@@ -393,7 +397,8 @@ var Signaliz = class {
393
397
  emails.length,
394
398
  startedAt,
395
399
  round,
396
- (item) => normalizeVerifyEmailResult(emails[item.index], item.raw)
400
+ (item) => normalizeVerifyEmailResult(emails[item.index], item.raw),
401
+ options
397
402
  );
398
403
  }
399
404
  async enrichCompanySignals(params) {
@@ -488,13 +493,14 @@ var Signaliz = class {
488
493
  await sleep2(Math.max(1, nextDelayMs));
489
494
  pending = nextPending;
490
495
  }
491
- const succeeded = results.filter((item) => item.success).length;
496
+ const compactedResults = compactExactDuplicateResults(results, options?.compactDuplicates === true);
497
+ const succeeded = compactedResults.filter((item) => item.success).length;
492
498
  return {
493
499
  total: companies.length,
494
500
  succeeded,
495
501
  failed: companies.length - succeeded,
496
502
  durationMs: Date.now() - startedAt,
497
- results
503
+ results: compactedResults
498
504
  };
499
505
  }
500
506
  async signalToCopy(params) {
@@ -535,13 +541,14 @@ var Signaliz = class {
535
541
  ...uniqueResults[deduplicated.sourceIndexByInput[index]],
536
542
  index
537
543
  }));
538
- const succeeded = results.filter((item) => item.success).length;
544
+ const compactedResults = compactExactDuplicateResults(results, options?.compactDuplicates === true);
545
+ const succeeded = compactedResults.filter((item) => item.success).length;
539
546
  return {
540
547
  total: requests.length,
541
548
  succeeded,
542
549
  failed: requests.length - succeeded,
543
550
  durationMs: Date.now() - startedAt,
544
- results
551
+ results: compactedResults
545
552
  };
546
553
  }
547
554
  async runSignalCopyBatchChunks(uniqueRequests, options) {
@@ -994,7 +1001,7 @@ function dedupeExactBatchItems(items, keyForItem) {
994
1001
  }
995
1002
  return { uniqueItems, sourceIndexByInput };
996
1003
  }
997
- function finalizeCoreBatch(total, startedAt, round, normalize) {
1004
+ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
998
1005
  const results = new Array(total);
999
1006
  for (const item of round) {
1000
1007
  if (!item.success || !item.raw) {
@@ -1011,15 +1018,31 @@ function finalizeCoreBatch(total, startedAt, round, normalize) {
1011
1018
  };
1012
1019
  }
1013
1020
  }
1014
- const succeeded = results.filter((item) => item.success).length;
1021
+ const compactedResults = compactExactDuplicateResults(results, options?.compactDuplicates === true);
1022
+ const succeeded = compactedResults.filter((item) => item.success).length;
1015
1023
  return {
1016
1024
  total,
1017
1025
  succeeded,
1018
1026
  failed: total - succeeded,
1019
1027
  durationMs: Date.now() - startedAt,
1020
- results
1028
+ results: compactedResults
1021
1029
  };
1022
1030
  }
1031
+ function compactExactDuplicateResults(results, enabled) {
1032
+ if (!enabled) return results;
1033
+ const sourceIndexByRaw = /* @__PURE__ */ new WeakMap();
1034
+ return results.map((item) => {
1035
+ if (!item.success || !item.data || typeof item.data !== "object") return item;
1036
+ const raw = item.data.raw;
1037
+ if (!raw || typeof raw !== "object") return item;
1038
+ const duplicateOf = sourceIndexByRaw.get(raw);
1039
+ if (duplicateOf !== void 0) {
1040
+ return { index: item.index, success: true, duplicateOf };
1041
+ }
1042
+ sourceIndexByRaw.set(raw, item.index);
1043
+ return item;
1044
+ });
1045
+ }
1023
1046
  function signalToCopyRequestBody(params) {
1024
1047
  return compact({
1025
1048
  company_domain: params.companyDomain,
package/dist/index.d.mts CHANGED
@@ -11,12 +11,16 @@ interface BatchOptions {
11
11
  concurrency?: number;
12
12
  /** Stable key for safely retrying an ambiguous recoverable batch submission. */
13
13
  idempotencyKey?: string;
14
+ /** Return exact repeated successes as duplicateOf references. Defaults to false. */
15
+ compactDuplicates?: boolean;
14
16
  }
15
17
  interface BatchItemResult<T> {
16
18
  index: number;
17
19
  success: boolean;
18
20
  data?: T;
19
21
  error?: string;
22
+ /** Zero-based input index containing the full result for this exact duplicate. */
23
+ duplicateOf?: number;
20
24
  }
21
25
  interface BatchResult<T> {
22
26
  total: number;
package/dist/index.d.ts CHANGED
@@ -11,12 +11,16 @@ interface BatchOptions {
11
11
  concurrency?: number;
12
12
  /** Stable key for safely retrying an ambiguous recoverable batch submission. */
13
13
  idempotencyKey?: string;
14
+ /** Return exact repeated successes as duplicateOf references. Defaults to false. */
15
+ compactDuplicates?: boolean;
14
16
  }
15
17
  interface BatchItemResult<T> {
16
18
  index: number;
17
19
  success: boolean;
18
20
  data?: T;
19
21
  error?: string;
22
+ /** Zero-based input index containing the full result for this exact duplicate. */
23
+ duplicateOf?: number;
20
24
  }
21
25
  interface BatchResult<T> {
22
26
  total: number;
package/dist/index.js CHANGED
@@ -49,16 +49,19 @@ function parseError(status, body) {
49
49
  details: body.error.details
50
50
  });
51
51
  }
52
+ const code = typeof body?.error_code === "string" && body.error_code.trim() ? body.error_code.trim() : `HTTP_${status}`;
52
53
  return new SignalizError({
53
- code: `HTTP_${status}`,
54
+ code,
54
55
  message: body?.message || body?.error || `Request failed with status ${status}`,
55
- errorType: mapErrorType(void 0, status)
56
+ errorType: mapErrorType(code, status),
57
+ details: body?.details || (body?.retry_eligible !== void 0 ? { retry_eligible: body.retry_eligible } : void 0)
56
58
  });
57
59
  }
58
60
  function mapErrorType(code, status) {
59
61
  if (code === "RATE_LIMITED" || status === 429) return "rate_limited";
60
62
  if (code === "VALIDATION_ERROR" || status === 400) return "validation";
61
63
  if (code === "NOT_FOUND" || status === 404) return "not_found";
64
+ if (code === "NO_SUPPORTED_SIGNAL") return "not_found";
62
65
  if (code === "AUTH_EXPIRED" || status === 401) return "auth_expired";
63
66
  if (code === "INSUFFICIENT_CREDITS" || status === 402) return "insufficient_credits";
64
67
  if (code === "TIMEOUT" || status === 504) return "timeout";
@@ -395,7 +398,8 @@ var Signaliz = class {
395
398
  params.length,
396
399
  startedAt,
397
400
  round,
398
- (item) => normalizeFindEmailResult(item.raw)
401
+ (item) => normalizeFindEmailResult(item.raw),
402
+ options
399
403
  );
400
404
  }
401
405
  async verifyEmail(email, options) {
@@ -420,7 +424,8 @@ var Signaliz = class {
420
424
  emails.length,
421
425
  startedAt,
422
426
  round,
423
- (item) => normalizeVerifyEmailResult(emails[item.index], item.raw)
427
+ (item) => normalizeVerifyEmailResult(emails[item.index], item.raw),
428
+ options
424
429
  );
425
430
  }
426
431
  async enrichCompanySignals(params) {
@@ -515,13 +520,14 @@ var Signaliz = class {
515
520
  await sleep2(Math.max(1, nextDelayMs));
516
521
  pending = nextPending;
517
522
  }
518
- const succeeded = results.filter((item) => item.success).length;
523
+ const compactedResults = compactExactDuplicateResults(results, options?.compactDuplicates === true);
524
+ const succeeded = compactedResults.filter((item) => item.success).length;
519
525
  return {
520
526
  total: companies.length,
521
527
  succeeded,
522
528
  failed: companies.length - succeeded,
523
529
  durationMs: Date.now() - startedAt,
524
- results
530
+ results: compactedResults
525
531
  };
526
532
  }
527
533
  async signalToCopy(params) {
@@ -562,13 +568,14 @@ var Signaliz = class {
562
568
  ...uniqueResults[deduplicated.sourceIndexByInput[index]],
563
569
  index
564
570
  }));
565
- const succeeded = results.filter((item) => item.success).length;
571
+ const compactedResults = compactExactDuplicateResults(results, options?.compactDuplicates === true);
572
+ const succeeded = compactedResults.filter((item) => item.success).length;
566
573
  return {
567
574
  total: requests.length,
568
575
  succeeded,
569
576
  failed: requests.length - succeeded,
570
577
  durationMs: Date.now() - startedAt,
571
- results
578
+ results: compactedResults
572
579
  };
573
580
  }
574
581
  async runSignalCopyBatchChunks(uniqueRequests, options) {
@@ -1021,7 +1028,7 @@ function dedupeExactBatchItems(items, keyForItem) {
1021
1028
  }
1022
1029
  return { uniqueItems, sourceIndexByInput };
1023
1030
  }
1024
- function finalizeCoreBatch(total, startedAt, round, normalize) {
1031
+ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
1025
1032
  const results = new Array(total);
1026
1033
  for (const item of round) {
1027
1034
  if (!item.success || !item.raw) {
@@ -1038,15 +1045,31 @@ function finalizeCoreBatch(total, startedAt, round, normalize) {
1038
1045
  };
1039
1046
  }
1040
1047
  }
1041
- const succeeded = results.filter((item) => item.success).length;
1048
+ const compactedResults = compactExactDuplicateResults(results, options?.compactDuplicates === true);
1049
+ const succeeded = compactedResults.filter((item) => item.success).length;
1042
1050
  return {
1043
1051
  total,
1044
1052
  succeeded,
1045
1053
  failed: total - succeeded,
1046
1054
  durationMs: Date.now() - startedAt,
1047
- results
1055
+ results: compactedResults
1048
1056
  };
1049
1057
  }
1058
+ function compactExactDuplicateResults(results, enabled) {
1059
+ if (!enabled) return results;
1060
+ const sourceIndexByRaw = /* @__PURE__ */ new WeakMap();
1061
+ return results.map((item) => {
1062
+ if (!item.success || !item.data || typeof item.data !== "object") return item;
1063
+ const raw = item.data.raw;
1064
+ if (!raw || typeof raw !== "object") return item;
1065
+ const duplicateOf = sourceIndexByRaw.get(raw);
1066
+ if (duplicateOf !== void 0) {
1067
+ return { index: item.index, success: true, duplicateOf };
1068
+ }
1069
+ sourceIndexByRaw.set(raw, item.index);
1070
+ return item;
1071
+ });
1072
+ }
1050
1073
  function signalToCopyRequestBody(params) {
1051
1074
  return compact({
1052
1075
  company_domain: params.companyDomain,
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Signaliz,
3
3
  SignalizError
4
- } from "./chunk-WKE2PNXT.mjs";
4
+ } from "./chunk-ZIYVY22X.mjs";
5
5
  export {
6
6
  Signaliz,
7
7
  SignalizError
@@ -53,16 +53,19 @@ function parseError(status, body) {
53
53
  details: body.error.details
54
54
  });
55
55
  }
56
+ const code = typeof body?.error_code === "string" && body.error_code.trim() ? body.error_code.trim() : `HTTP_${status}`;
56
57
  return new SignalizError({
57
- code: `HTTP_${status}`,
58
+ code,
58
59
  message: body?.message || body?.error || `Request failed with status ${status}`,
59
- errorType: mapErrorType(void 0, status)
60
+ errorType: mapErrorType(code, status),
61
+ details: body?.details || (body?.retry_eligible !== void 0 ? { retry_eligible: body.retry_eligible } : void 0)
60
62
  });
61
63
  }
62
64
  function mapErrorType(code, status) {
63
65
  if (code === "RATE_LIMITED" || status === 429) return "rate_limited";
64
66
  if (code === "VALIDATION_ERROR" || status === 400) return "validation";
65
67
  if (code === "NOT_FOUND" || status === 404) return "not_found";
68
+ if (code === "NO_SUPPORTED_SIGNAL") return "not_found";
66
69
  if (code === "AUTH_EXPIRED" || status === 401) return "auth_expired";
67
70
  if (code === "INSUFFICIENT_CREDITS" || status === 402) return "insufficient_credits";
68
71
  if (code === "TIMEOUT" || status === 504) return "timeout";
@@ -399,7 +402,8 @@ var Signaliz = class {
399
402
  params.length,
400
403
  startedAt,
401
404
  round,
402
- (item) => normalizeFindEmailResult(item.raw)
405
+ (item) => normalizeFindEmailResult(item.raw),
406
+ options
403
407
  );
404
408
  }
405
409
  async verifyEmail(email, options) {
@@ -424,7 +428,8 @@ var Signaliz = class {
424
428
  emails.length,
425
429
  startedAt,
426
430
  round,
427
- (item) => normalizeVerifyEmailResult(emails[item.index], item.raw)
431
+ (item) => normalizeVerifyEmailResult(emails[item.index], item.raw),
432
+ options
428
433
  );
429
434
  }
430
435
  async enrichCompanySignals(params) {
@@ -519,13 +524,14 @@ var Signaliz = class {
519
524
  await sleep2(Math.max(1, nextDelayMs));
520
525
  pending = nextPending;
521
526
  }
522
- const succeeded = results.filter((item) => item.success).length;
527
+ const compactedResults = compactExactDuplicateResults(results, options?.compactDuplicates === true);
528
+ const succeeded = compactedResults.filter((item) => item.success).length;
523
529
  return {
524
530
  total: companies.length,
525
531
  succeeded,
526
532
  failed: companies.length - succeeded,
527
533
  durationMs: Date.now() - startedAt,
528
- results
534
+ results: compactedResults
529
535
  };
530
536
  }
531
537
  async signalToCopy(params) {
@@ -566,13 +572,14 @@ var Signaliz = class {
566
572
  ...uniqueResults[deduplicated.sourceIndexByInput[index]],
567
573
  index
568
574
  }));
569
- const succeeded = results.filter((item) => item.success).length;
575
+ const compactedResults = compactExactDuplicateResults(results, options?.compactDuplicates === true);
576
+ const succeeded = compactedResults.filter((item) => item.success).length;
570
577
  return {
571
578
  total: requests.length,
572
579
  succeeded,
573
580
  failed: requests.length - succeeded,
574
581
  durationMs: Date.now() - startedAt,
575
- results
582
+ results: compactedResults
576
583
  };
577
584
  }
578
585
  async runSignalCopyBatchChunks(uniqueRequests, options) {
@@ -1025,7 +1032,7 @@ function dedupeExactBatchItems(items, keyForItem) {
1025
1032
  }
1026
1033
  return { uniqueItems, sourceIndexByInput };
1027
1034
  }
1028
- function finalizeCoreBatch(total, startedAt, round, normalize) {
1035
+ function finalizeCoreBatch(total, startedAt, round, normalize, options) {
1029
1036
  const results = new Array(total);
1030
1037
  for (const item of round) {
1031
1038
  if (!item.success || !item.raw) {
@@ -1042,15 +1049,31 @@ function finalizeCoreBatch(total, startedAt, round, normalize) {
1042
1049
  };
1043
1050
  }
1044
1051
  }
1045
- const succeeded = results.filter((item) => item.success).length;
1052
+ const compactedResults = compactExactDuplicateResults(results, options?.compactDuplicates === true);
1053
+ const succeeded = compactedResults.filter((item) => item.success).length;
1046
1054
  return {
1047
1055
  total,
1048
1056
  succeeded,
1049
1057
  failed: total - succeeded,
1050
1058
  durationMs: Date.now() - startedAt,
1051
- results
1059
+ results: compactedResults
1052
1060
  };
1053
1061
  }
1062
+ function compactExactDuplicateResults(results, enabled) {
1063
+ if (!enabled) return results;
1064
+ const sourceIndexByRaw = /* @__PURE__ */ new WeakMap();
1065
+ return results.map((item) => {
1066
+ if (!item.success || !item.data || typeof item.data !== "object") return item;
1067
+ const raw = item.data.raw;
1068
+ if (!raw || typeof raw !== "object") return item;
1069
+ const duplicateOf = sourceIndexByRaw.get(raw);
1070
+ if (duplicateOf !== void 0) {
1071
+ return { index: item.index, success: true, duplicateOf };
1072
+ }
1073
+ sourceIndexByRaw.set(raw, item.index);
1074
+ return item;
1075
+ });
1076
+ }
1054
1077
  function signalToCopyRequestBody(params) {
1055
1078
  return compact({
1056
1079
  company_domain: params.companyDomain,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Signaliz
4
- } from "./chunk-WKE2PNXT.mjs";
4
+ } from "./chunk-ZIYVY22X.mjs";
5
5
 
6
6
  // src/mcp-config.ts
7
7
  import * as fs from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signaliz/sdk",
3
- "version": "1.0.36",
3
+ "version": "1.0.38",
4
4
  "description": "Signaliz SDK for Find Email, Verify Email, Company Signal Enrichment, and Signal to Copy AI.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",