@signaliz/sdk 1.0.31 → 1.0.32

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
@@ -77,10 +77,12 @@ resumes long-running research through the same `/company-signals` endpoint;
77
77
  callers never need an internal Trigger.dev status URL. The SDK follows the
78
78
  server's adaptive polling hints by default and still honors `pollIntervalMs`
79
79
  when a caller explicitly overrides the cadence.
80
- All four products are transported in 25-row REST chunks. Exact duplicate tasks
81
- are single-flighted across the full batch before chunking, without changing
82
- input order or result cardinality. Signal to Copy also shares company research
83
- across copy recipients.
80
+ Exact duplicate tasks are single-flighted across each full batch without
81
+ changing input order or result cardinality. Find Email, Verify Email, and
82
+ Company Signal Enrichment use 25-row REST chunks. Signal to Copy batches larger
83
+ than 25 use one recoverable REST job when they can reuse available signal data;
84
+ fresh or deep-search requests keep the 25-row path. Signal to Copy also shares
85
+ company research across copy recipients.
84
86
 
85
87
  Company Signal Enrichment defaults `online` and `enableDeepSearch` to `true`
86
88
  unless the caller explicitly disables them. Signal to Copy AI returns three
@@ -518,6 +518,24 @@ var Signaliz = class {
518
518
  poll_interval_ms: params.pollIntervalMs
519
519
  }));
520
520
  const uniqueRequests = deduplicated.uniqueItems;
521
+ const canUseRecoverableAvailableDataJob = uniqueRequests.length > 25 && uniqueRequests.every(
522
+ (params) => params.waitForResult !== false && params.skipCache !== true && params.enableDeepSearch !== true && params.maxWaitMs === void 0 && params.pollIntervalMs === void 0
523
+ );
524
+ const uniqueResults = canUseRecoverableAvailableDataJob ? await this.runAvailableSignalCopyBatchJob(uniqueRequests) : await this.runSignalCopyBatchChunks(uniqueRequests, options);
525
+ const results = requests.map((_, index) => ({
526
+ ...uniqueResults[deduplicated.sourceIndexByInput[index]],
527
+ index
528
+ }));
529
+ const succeeded = results.filter((item) => item.success).length;
530
+ return {
531
+ total: requests.length,
532
+ succeeded,
533
+ failed: requests.length - succeeded,
534
+ durationMs: Date.now() - startedAt,
535
+ results
536
+ };
537
+ }
538
+ async runSignalCopyBatchChunks(uniqueRequests, options) {
521
539
  const chunks = [];
522
540
  for (let offset = 0; offset < uniqueRequests.length; offset += 25) {
523
541
  chunks.push({ offset, requests: uniqueRequests.slice(offset, offset + 25) });
@@ -545,18 +563,55 @@ var Signaliz = class {
545
563
  uniqueResults[chunk.offset + item.index] = { ...item, index: chunk.offset + item.index };
546
564
  }
547
565
  }
548
- const results = requests.map((_, index) => ({
549
- ...uniqueResults[deduplicated.sourceIndexByInput[index]],
550
- index
551
- }));
552
- const succeeded = results.filter((item) => item.success).length;
553
- return {
554
- total: requests.length,
555
- succeeded,
556
- failed: requests.length - succeeded,
557
- durationMs: Date.now() - startedAt,
558
- results
559
- };
566
+ return uniqueResults;
567
+ }
568
+ async runAvailableSignalCopyBatchJob(requests) {
569
+ const startedAt = Date.now();
570
+ const maxWaitMs = 20 * 6e4;
571
+ let status = await this.client.post("api/v1/signal-to-copy", {
572
+ requests: requests.map(signalToCopyRequestBody)
573
+ });
574
+ const jobId = String(status.job_id || "").trim();
575
+ if (!jobId) throw new Error("Signal to Copy batch did not return a recoverable job_id");
576
+ while (!["completed", "partial", "failed"].includes(String(status.status || "").toLowerCase())) {
577
+ if (Date.now() - startedAt >= maxWaitMs) {
578
+ throw new Error(`Signal to Copy batch ${jobId} did not complete within ${maxWaitMs}ms`);
579
+ }
580
+ const retryAfterMs = Number(status.next_poll_after_seconds || 2) * 1e3;
581
+ await sleep2(Math.min(Math.max(250, retryAfterMs), maxWaitMs - (Date.now() - startedAt)));
582
+ status = await this.client.post("api/v1/signal-to-copy", {
583
+ job_id: jobId,
584
+ page: 1,
585
+ page_size: 500
586
+ });
587
+ }
588
+ const totalPages = Math.max(1, Number(status.total_pages || 1));
589
+ const pages = [Array.isArray(status.results) ? status.results : []];
590
+ if (totalPages > 1) {
591
+ const remainingPages = await Promise.all(Array.from(
592
+ { length: totalPages - 1 },
593
+ (_, index) => this.client.post("api/v1/signal-to-copy", {
594
+ job_id: jobId,
595
+ page: index + 2,
596
+ page_size: 500
597
+ })
598
+ ));
599
+ for (const page of remainingPages) pages.push(Array.isArray(page.results) ? page.results : []);
600
+ }
601
+ const rows = pages.flat();
602
+ if (rows.length !== requests.length) {
603
+ throw new Error(`Signal to Copy batch returned ${rows.length} results for ${requests.length} requests`);
604
+ }
605
+ const results = new Array(requests.length);
606
+ for (const row of rows) {
607
+ const index = Number(row.index);
608
+ if (!Number.isInteger(index) || index < 0 || index >= requests.length) {
609
+ throw new Error("Signal to Copy batch returned an invalid result index");
610
+ }
611
+ results[index] = row.success === false ? { index, success: false, error: row.error || row.message || "Signal to Copy failed" } : { index, success: true, data: normalizeSignalToCopyResult(row) };
612
+ }
613
+ if (results.some((item) => !item)) throw new Error("Signal to Copy batch returned incomplete indexed results");
614
+ return results;
560
615
  }
561
616
  async runSignalCopyBatchChunk(requests, concurrency) {
562
617
  const startedAt = Date.now();
package/dist/index.d.mts CHANGED
@@ -203,6 +203,8 @@ declare class Signaliz {
203
203
  enrichCompanies(companies: CompanySignalEnrichmentParams[], options?: BatchOptions): Promise<BatchResult<CompanySignalEnrichmentResult>>;
204
204
  signalToCopy(params: SignalToCopyParams): Promise<SignalToCopyResult>;
205
205
  createSignalCopyBatch(requests: SignalToCopyParams[], options?: BatchOptions): Promise<BatchResult<SignalToCopyResult>>;
206
+ private runSignalCopyBatchChunks;
207
+ private runAvailableSignalCopyBatchJob;
206
208
  private runSignalCopyBatchChunk;
207
209
  private runCoreBatchRound;
208
210
  listTools(): Promise<MCPToolInfo[]>;
package/dist/index.d.ts CHANGED
@@ -203,6 +203,8 @@ declare class Signaliz {
203
203
  enrichCompanies(companies: CompanySignalEnrichmentParams[], options?: BatchOptions): Promise<BatchResult<CompanySignalEnrichmentResult>>;
204
204
  signalToCopy(params: SignalToCopyParams): Promise<SignalToCopyResult>;
205
205
  createSignalCopyBatch(requests: SignalToCopyParams[], options?: BatchOptions): Promise<BatchResult<SignalToCopyResult>>;
206
+ private runSignalCopyBatchChunks;
207
+ private runAvailableSignalCopyBatchJob;
206
208
  private runSignalCopyBatchChunk;
207
209
  private runCoreBatchRound;
208
210
  listTools(): Promise<MCPToolInfo[]>;
package/dist/index.js CHANGED
@@ -545,6 +545,24 @@ var Signaliz = class {
545
545
  poll_interval_ms: params.pollIntervalMs
546
546
  }));
547
547
  const uniqueRequests = deduplicated.uniqueItems;
548
+ const canUseRecoverableAvailableDataJob = uniqueRequests.length > 25 && uniqueRequests.every(
549
+ (params) => params.waitForResult !== false && params.skipCache !== true && params.enableDeepSearch !== true && params.maxWaitMs === void 0 && params.pollIntervalMs === void 0
550
+ );
551
+ const uniqueResults = canUseRecoverableAvailableDataJob ? await this.runAvailableSignalCopyBatchJob(uniqueRequests) : await this.runSignalCopyBatchChunks(uniqueRequests, options);
552
+ const results = requests.map((_, index) => ({
553
+ ...uniqueResults[deduplicated.sourceIndexByInput[index]],
554
+ index
555
+ }));
556
+ const succeeded = results.filter((item) => item.success).length;
557
+ return {
558
+ total: requests.length,
559
+ succeeded,
560
+ failed: requests.length - succeeded,
561
+ durationMs: Date.now() - startedAt,
562
+ results
563
+ };
564
+ }
565
+ async runSignalCopyBatchChunks(uniqueRequests, options) {
548
566
  const chunks = [];
549
567
  for (let offset = 0; offset < uniqueRequests.length; offset += 25) {
550
568
  chunks.push({ offset, requests: uniqueRequests.slice(offset, offset + 25) });
@@ -572,18 +590,55 @@ var Signaliz = class {
572
590
  uniqueResults[chunk.offset + item.index] = { ...item, index: chunk.offset + item.index };
573
591
  }
574
592
  }
575
- const results = requests.map((_, index) => ({
576
- ...uniqueResults[deduplicated.sourceIndexByInput[index]],
577
- index
578
- }));
579
- const succeeded = results.filter((item) => item.success).length;
580
- return {
581
- total: requests.length,
582
- succeeded,
583
- failed: requests.length - succeeded,
584
- durationMs: Date.now() - startedAt,
585
- results
586
- };
593
+ return uniqueResults;
594
+ }
595
+ async runAvailableSignalCopyBatchJob(requests) {
596
+ const startedAt = Date.now();
597
+ const maxWaitMs = 20 * 6e4;
598
+ let status = await this.client.post("api/v1/signal-to-copy", {
599
+ requests: requests.map(signalToCopyRequestBody)
600
+ });
601
+ const jobId = String(status.job_id || "").trim();
602
+ if (!jobId) throw new Error("Signal to Copy batch did not return a recoverable job_id");
603
+ while (!["completed", "partial", "failed"].includes(String(status.status || "").toLowerCase())) {
604
+ if (Date.now() - startedAt >= maxWaitMs) {
605
+ throw new Error(`Signal to Copy batch ${jobId} did not complete within ${maxWaitMs}ms`);
606
+ }
607
+ const retryAfterMs = Number(status.next_poll_after_seconds || 2) * 1e3;
608
+ await sleep2(Math.min(Math.max(250, retryAfterMs), maxWaitMs - (Date.now() - startedAt)));
609
+ status = await this.client.post("api/v1/signal-to-copy", {
610
+ job_id: jobId,
611
+ page: 1,
612
+ page_size: 500
613
+ });
614
+ }
615
+ const totalPages = Math.max(1, Number(status.total_pages || 1));
616
+ const pages = [Array.isArray(status.results) ? status.results : []];
617
+ if (totalPages > 1) {
618
+ const remainingPages = await Promise.all(Array.from(
619
+ { length: totalPages - 1 },
620
+ (_, index) => this.client.post("api/v1/signal-to-copy", {
621
+ job_id: jobId,
622
+ page: index + 2,
623
+ page_size: 500
624
+ })
625
+ ));
626
+ for (const page of remainingPages) pages.push(Array.isArray(page.results) ? page.results : []);
627
+ }
628
+ const rows = pages.flat();
629
+ if (rows.length !== requests.length) {
630
+ throw new Error(`Signal to Copy batch returned ${rows.length} results for ${requests.length} requests`);
631
+ }
632
+ const results = new Array(requests.length);
633
+ for (const row of rows) {
634
+ const index = Number(row.index);
635
+ if (!Number.isInteger(index) || index < 0 || index >= requests.length) {
636
+ throw new Error("Signal to Copy batch returned an invalid result index");
637
+ }
638
+ results[index] = row.success === false ? { index, success: false, error: row.error || row.message || "Signal to Copy failed" } : { index, success: true, data: normalizeSignalToCopyResult(row) };
639
+ }
640
+ if (results.some((item) => !item)) throw new Error("Signal to Copy batch returned incomplete indexed results");
641
+ return results;
587
642
  }
588
643
  async runSignalCopyBatchChunk(requests, concurrency) {
589
644
  const startedAt = Date.now();
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Signaliz,
3
3
  SignalizError
4
- } from "./chunk-P3ICLKAE.mjs";
4
+ } from "./chunk-JO4MYKSK.mjs";
5
5
  export {
6
6
  Signaliz,
7
7
  SignalizError
@@ -549,6 +549,24 @@ var Signaliz = class {
549
549
  poll_interval_ms: params.pollIntervalMs
550
550
  }));
551
551
  const uniqueRequests = deduplicated.uniqueItems;
552
+ const canUseRecoverableAvailableDataJob = uniqueRequests.length > 25 && uniqueRequests.every(
553
+ (params) => params.waitForResult !== false && params.skipCache !== true && params.enableDeepSearch !== true && params.maxWaitMs === void 0 && params.pollIntervalMs === void 0
554
+ );
555
+ const uniqueResults = canUseRecoverableAvailableDataJob ? await this.runAvailableSignalCopyBatchJob(uniqueRequests) : await this.runSignalCopyBatchChunks(uniqueRequests, options);
556
+ const results = requests.map((_, index) => ({
557
+ ...uniqueResults[deduplicated.sourceIndexByInput[index]],
558
+ index
559
+ }));
560
+ const succeeded = results.filter((item) => item.success).length;
561
+ return {
562
+ total: requests.length,
563
+ succeeded,
564
+ failed: requests.length - succeeded,
565
+ durationMs: Date.now() - startedAt,
566
+ results
567
+ };
568
+ }
569
+ async runSignalCopyBatchChunks(uniqueRequests, options) {
552
570
  const chunks = [];
553
571
  for (let offset = 0; offset < uniqueRequests.length; offset += 25) {
554
572
  chunks.push({ offset, requests: uniqueRequests.slice(offset, offset + 25) });
@@ -576,18 +594,55 @@ var Signaliz = class {
576
594
  uniqueResults[chunk.offset + item.index] = { ...item, index: chunk.offset + item.index };
577
595
  }
578
596
  }
579
- const results = requests.map((_, index) => ({
580
- ...uniqueResults[deduplicated.sourceIndexByInput[index]],
581
- index
582
- }));
583
- const succeeded = results.filter((item) => item.success).length;
584
- return {
585
- total: requests.length,
586
- succeeded,
587
- failed: requests.length - succeeded,
588
- durationMs: Date.now() - startedAt,
589
- results
590
- };
597
+ return uniqueResults;
598
+ }
599
+ async runAvailableSignalCopyBatchJob(requests) {
600
+ const startedAt = Date.now();
601
+ const maxWaitMs = 20 * 6e4;
602
+ let status = await this.client.post("api/v1/signal-to-copy", {
603
+ requests: requests.map(signalToCopyRequestBody)
604
+ });
605
+ const jobId = String(status.job_id || "").trim();
606
+ if (!jobId) throw new Error("Signal to Copy batch did not return a recoverable job_id");
607
+ while (!["completed", "partial", "failed"].includes(String(status.status || "").toLowerCase())) {
608
+ if (Date.now() - startedAt >= maxWaitMs) {
609
+ throw new Error(`Signal to Copy batch ${jobId} did not complete within ${maxWaitMs}ms`);
610
+ }
611
+ const retryAfterMs = Number(status.next_poll_after_seconds || 2) * 1e3;
612
+ await sleep2(Math.min(Math.max(250, retryAfterMs), maxWaitMs - (Date.now() - startedAt)));
613
+ status = await this.client.post("api/v1/signal-to-copy", {
614
+ job_id: jobId,
615
+ page: 1,
616
+ page_size: 500
617
+ });
618
+ }
619
+ const totalPages = Math.max(1, Number(status.total_pages || 1));
620
+ const pages = [Array.isArray(status.results) ? status.results : []];
621
+ if (totalPages > 1) {
622
+ const remainingPages = await Promise.all(Array.from(
623
+ { length: totalPages - 1 },
624
+ (_, index) => this.client.post("api/v1/signal-to-copy", {
625
+ job_id: jobId,
626
+ page: index + 2,
627
+ page_size: 500
628
+ })
629
+ ));
630
+ for (const page of remainingPages) pages.push(Array.isArray(page.results) ? page.results : []);
631
+ }
632
+ const rows = pages.flat();
633
+ if (rows.length !== requests.length) {
634
+ throw new Error(`Signal to Copy batch returned ${rows.length} results for ${requests.length} requests`);
635
+ }
636
+ const results = new Array(requests.length);
637
+ for (const row of rows) {
638
+ const index = Number(row.index);
639
+ if (!Number.isInteger(index) || index < 0 || index >= requests.length) {
640
+ throw new Error("Signal to Copy batch returned an invalid result index");
641
+ }
642
+ results[index] = row.success === false ? { index, success: false, error: row.error || row.message || "Signal to Copy failed" } : { index, success: true, data: normalizeSignalToCopyResult(row) };
643
+ }
644
+ if (results.some((item) => !item)) throw new Error("Signal to Copy batch returned incomplete indexed results");
645
+ return results;
591
646
  }
592
647
  async runSignalCopyBatchChunk(requests, concurrency) {
593
648
  const startedAt = Date.now();
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Signaliz
4
- } from "./chunk-P3ICLKAE.mjs";
4
+ } from "./chunk-JO4MYKSK.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.31",
3
+ "version": "1.0.32",
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",