@signaliz/sdk 1.0.29 → 1.0.31

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/dist/index.js CHANGED
@@ -380,89 +380,51 @@ var Signaliz = class {
380
380
  this.client = new HttpClient(config);
381
381
  }
382
382
  async findEmail(params) {
383
- const data = await this.client.post("api/v1/find-email", compact({
384
- company_domain: params.companyDomain,
385
- full_name: params.fullName,
386
- first_name: params.firstName,
387
- last_name: params.lastName,
388
- linkedin_url: params.linkedinUrl,
389
- company_name: params.companyName,
390
- skip_cache: params.skipCache
391
- }));
392
- const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
393
- const found = Boolean(email) && data.found !== false;
394
- const verificationStatus = data.verification_status ?? data.status ?? "unknown";
395
- const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
396
- const verificationFreshness = rawFreshness === "fresh" || rawFreshness === "stale" ? rawFreshness : "unknown";
397
- const needsReverification = data.needs_reverification === true || verificationFreshness === "stale";
398
- const explicitlyNotSendSafe = data.verified_for_sending === false || needsReverification;
399
- const verified = !explicitlyNotSendSafe && (data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
400
- const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
401
- return {
402
- success: data.success !== false && found,
403
- found,
404
- email,
405
- firstName: data.first_name,
406
- lastName: data.last_name,
407
- confidence: data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
408
- verificationStatus,
409
- isVerified: verified,
410
- isVerifiedForSending: !needsReverification && data.verified_for_sending === true,
411
- isCatchAll: data.email_is_catch_all === true || data.is_catch_all === true,
412
- verificationFreshness,
413
- verificationAgeDays,
414
- verifiedAt: typeof data.verified_at === "string" ? data.verified_at : null,
415
- needsReverification,
416
- providerUsed: data.provider_used ?? data.provider ?? data.email_source ?? data.source ?? "unknown",
417
- error: found ? void 0 : data.error ?? "No verified email found",
418
- errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
419
- raw: data
420
- };
383
+ const data = await this.client.post("api/v1/find-email", findEmailRequestBody(params));
384
+ return normalizeFindEmailResult(data);
421
385
  }
422
386
  async findEmails(params, options) {
423
- return runBatch(params, (item) => this.findEmail(item), options);
387
+ validateBatchSize(params);
388
+ const startedAt = Date.now();
389
+ const round = await this.runCoreBatchRound(
390
+ "api/v1/find-email",
391
+ params.map((item, index) => ({ index, request: findEmailRequestBody(item) })),
392
+ options
393
+ );
394
+ return finalizeCoreBatch(
395
+ params.length,
396
+ startedAt,
397
+ round,
398
+ (item) => normalizeFindEmailResult(item.raw)
399
+ );
424
400
  }
425
401
  async verifyEmail(email, options) {
426
402
  const data = await this.client.post("api/v1/verify-email", {
427
403
  email,
428
404
  skip_cache: options?.skipCache
429
405
  });
430
- const verificationStatus = String(data.verification_status ?? "").toLowerCase();
431
- const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
432
- return {
433
- email: data.email ?? email,
434
- isValid: data.is_valid ?? data.valid ?? verified,
435
- isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
436
- isCatchAll: data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
437
- confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
438
- provider: data.provider,
439
- verificationSource: data.verification_source,
440
- raw: data
441
- };
406
+ return normalizeVerifyEmailResult(email, data);
442
407
  }
443
408
  async verifyEmails(emails, options) {
444
- return runBatch(emails, (email) => this.verifyEmail(email, { skipCache: options?.skipCache }), options);
409
+ validateBatchSize(emails);
410
+ const startedAt = Date.now();
411
+ const round = await this.runCoreBatchRound(
412
+ "api/v1/verify-email",
413
+ emails.map((email, index) => ({
414
+ index,
415
+ request: { email, skip_cache: options?.skipCache }
416
+ })),
417
+ options
418
+ );
419
+ return finalizeCoreBatch(
420
+ emails.length,
421
+ startedAt,
422
+ round,
423
+ (item) => normalizeVerifyEmailResult(emails[item.index], item.raw)
424
+ );
445
425
  }
446
426
  async enrichCompanySignals(params) {
447
- const online = params.online ?? true;
448
- const request = compact({
449
- signal_run_id: params.signalRunId,
450
- company_domain: params.companyDomain,
451
- company_name: params.companyName,
452
- research_prompt: params.researchPrompt,
453
- signal_types: params.signalTypes,
454
- target_signal_count: params.targetSignalCount,
455
- lookback_days: params.lookbackDays,
456
- online,
457
- enable_deep_search: params.enableDeepSearch ?? online,
458
- enable_outreach_intelligence: params.enableOutreachIntelligence,
459
- enable_predictive_intelligence: params.enablePredictiveIntelligence,
460
- skip_cache: params.skipCache,
461
- // REST always returns a resumable run instead of holding the connection;
462
- // waitForResult controls this SDK's polling loop below.
463
- wait_for_result: false,
464
- max_wait_ms: params.maxWaitMs
465
- });
427
+ const request = companySignalRequestBody(params);
466
428
  let data = await this.client.post("api/v1/company-signals", request);
467
429
  if (params.waitForResult !== false && data.run_id && isPendingSignalResponse(data)) {
468
430
  const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
@@ -490,47 +452,68 @@ var Signaliz = class {
490
452
  throw new Error(`Company signal enrichment ${data.run_id} did not complete within ${maxWaitMs}ms`);
491
453
  }
492
454
  }
493
- return {
494
- success: data.success ?? true,
495
- status: data.status,
496
- signalRunId: data.signal_run_id ?? data.run_id,
497
- company: {
498
- name: data.company?.name ?? params.companyName ?? null,
499
- domain: data.company?.domain ?? params.companyDomain ?? null
500
- },
501
- signals: (data.signals ?? []).map((signal) => {
502
- const metadata = signal.metadata && typeof signal.metadata === "object" && !Array.isArray(signal.metadata) ? signal.metadata : void 0;
503
- return {
504
- id: signal.id,
505
- title: signal.title ?? "",
506
- type: signal.type ?? signal.signal_type ?? "unknown",
507
- content: signal.content ?? signal.description ?? "",
508
- date: signal.date ?? signal.detected_at ?? null,
509
- datePrecision: signal.date_precision,
510
- sourceUrl: signal.source_url ?? signal.url ?? null,
511
- sourceType: signal.source_type,
512
- sourceProvenance: signal.source_provenance,
513
- confidence: signal.confidence ?? signal.confidence_score ?? null,
514
- entityConfidence: signal.entity_confidence ?? metadata?.entity_confidence ?? null,
515
- signalFamily: signal.signal_family,
516
- eventType: signal.signal_event_type,
517
- eventLabel: signal.signal_event_label,
518
- classification: signal.signal_classification ?? null,
519
- derived: signal.derived === true,
520
- evidencePublishedDate: signal.evidence_published_date ?? metadata?.evidence_published_date ?? null,
521
- signalFeedSource: signal.signal_feed_source ?? metadata?.signal_feed_source,
522
- metadata
523
- };
524
- }),
525
- signalCount: data.signal_count ?? data.total_signals ?? data.signals?.length ?? 0,
526
- intelligence: data.intelligence ?? null,
527
- credits: data.credits,
528
- metadata: data.metadata,
529
- raw: data
530
- };
455
+ return normalizeCompanySignalResult(params, data);
531
456
  }
532
457
  async enrichCompanies(companies, options) {
533
- return runBatch(companies, (company) => this.enrichCompanySignals(company), options);
458
+ validateBatchSize(companies);
459
+ const startedAt = Date.now();
460
+ const results = new Array(companies.length);
461
+ let pending = companies.map((params, index) => ({
462
+ index,
463
+ request: companySignalRequestBody(params)
464
+ }));
465
+ while (pending.length > 0) {
466
+ const round = await this.runCoreBatchRound("api/v1/company-signals", pending, options);
467
+ const taskByIndex = new Map(pending.map((task) => [task.index, task]));
468
+ const nextPending = [];
469
+ let nextDelayMs = 6e4;
470
+ for (const item of round) {
471
+ const params = companies[item.index];
472
+ const task = taskByIndex.get(item.index);
473
+ if (!item.success || !item.raw) {
474
+ results[item.index] = { index: item.index, success: false, error: item.error || "Company Signal batch request failed" };
475
+ continue;
476
+ }
477
+ if (!isPendingSignalResponse(item.raw) || params.waitForResult === false) {
478
+ results[item.index] = { index: item.index, success: true, data: normalizeCompanySignalResult(params, item.raw) };
479
+ continue;
480
+ }
481
+ const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
482
+ if (Date.now() - startedAt >= maxWaitMs) {
483
+ results[item.index] = {
484
+ index: item.index,
485
+ success: false,
486
+ error: `Company signal enrichment ${item.raw.signal_run_id || item.raw.run_id || ""} did not complete within ${maxWaitMs}ms`
487
+ };
488
+ continue;
489
+ }
490
+ const signalRunId = item.raw.signal_run_id || item.raw.run_id;
491
+ if (!signalRunId) {
492
+ results[item.index] = { index: item.index, success: false, error: "Company signal enrichment is processing without a signal_run_id" };
493
+ continue;
494
+ }
495
+ nextDelayMs = Math.min(
496
+ nextDelayMs,
497
+ signalPollDelayMs(item.raw, params.pollIntervalMs),
498
+ maxWaitMs - (Date.now() - startedAt)
499
+ );
500
+ nextPending.push({
501
+ ...task,
502
+ request: { ...task.request, signal_run_id: signalRunId }
503
+ });
504
+ }
505
+ if (nextPending.length === 0) break;
506
+ await sleep2(Math.max(1, nextDelayMs));
507
+ pending = nextPending;
508
+ }
509
+ const succeeded = results.filter((item) => item.success).length;
510
+ return {
511
+ total: companies.length,
512
+ succeeded,
513
+ failed: companies.length - succeeded,
514
+ durationMs: Date.now() - startedAt,
515
+ results
516
+ };
534
517
  }
535
518
  async signalToCopy(params) {
536
519
  const request = signalToCopyRequestBody(params);
@@ -553,29 +536,31 @@ var Signaliz = class {
553
536
  return normalizeSignalToCopyResult(data);
554
537
  }
555
538
  async createSignalCopyBatch(requests, options) {
556
- if (!Array.isArray(requests) || requests.length === 0) {
557
- throw new Error("Signaliz batch requests require at least one item");
558
- }
559
- if (requests.length > 5e3) {
560
- throw new Error(`Signaliz batch requests support at most 5,000 items; received ${requests.length}`);
561
- }
539
+ validateBatchSize(requests);
562
540
  const startedAt = Date.now();
541
+ const deduplicated = dedupeExactBatchItems(requests, (params) => JSON.stringify({
542
+ request: signalToCopyRequestBody(params),
543
+ wait_for_result: params.waitForResult,
544
+ max_wait_ms: params.maxWaitMs,
545
+ poll_interval_ms: params.pollIntervalMs
546
+ }));
547
+ const uniqueRequests = deduplicated.uniqueItems;
563
548
  const chunks = [];
564
- for (let offset = 0; offset < requests.length; offset += 25) {
565
- chunks.push({ offset, requests: requests.slice(offset, offset + 25) });
549
+ for (let offset = 0; offset < uniqueRequests.length; offset += 25) {
550
+ chunks.push({ offset, requests: uniqueRequests.slice(offset, offset + 25) });
566
551
  }
567
- const serverConcurrency = Math.min(10, options?.concurrency ?? 10);
552
+ const { serverConcurrency, chunkConcurrency } = batchConcurrencyPlan(options);
568
553
  const chunkBatch = await runBatch(
569
554
  chunks,
570
555
  (chunk) => this.runSignalCopyBatchChunk(chunk.requests, serverConcurrency),
571
- options
556
+ { concurrency: chunkConcurrency }
572
557
  );
573
- const results = new Array(requests.length);
558
+ const uniqueResults = new Array(uniqueRequests.length);
574
559
  for (const chunkResult of chunkBatch.results) {
575
560
  const chunk = chunks[chunkResult.index];
576
561
  if (!chunkResult.success || !chunkResult.data) {
577
562
  for (let index = 0; index < chunk.requests.length; index += 1) {
578
- results[chunk.offset + index] = {
563
+ uniqueResults[chunk.offset + index] = {
579
564
  index: chunk.offset + index,
580
565
  success: false,
581
566
  error: chunkResult.error || "Signal to Copy batch request failed"
@@ -584,9 +569,13 @@ var Signaliz = class {
584
569
  continue;
585
570
  }
586
571
  for (const item of chunkResult.data) {
587
- results[chunk.offset + item.index] = { ...item, index: chunk.offset + item.index };
572
+ uniqueResults[chunk.offset + item.index] = { ...item, index: chunk.offset + item.index };
588
573
  }
589
574
  }
575
+ const results = requests.map((_, index) => ({
576
+ ...uniqueResults[deduplicated.sourceIndexByInput[index]],
577
+ index
578
+ }));
590
579
  const succeeded = results.filter((item) => item.success).length;
591
580
  return {
592
581
  total: requests.length,
@@ -658,6 +647,55 @@ var Signaliz = class {
658
647
  }
659
648
  return results;
660
649
  }
650
+ async runCoreBatchRound(path, tasks, options) {
651
+ const { serverConcurrency, chunkConcurrency } = batchConcurrencyPlan(options);
652
+ const deduplicated = dedupeExactBatchItems(tasks, (task) => JSON.stringify(task.request));
653
+ const uniqueTasks = deduplicated.uniqueItems;
654
+ const chunks = [];
655
+ for (let offset = 0; offset < uniqueTasks.length; offset += 25) {
656
+ chunks.push({ offset, tasks: uniqueTasks.slice(offset, offset + 25) });
657
+ }
658
+ const chunkBatch = await runBatch(chunks, async (chunk) => {
659
+ const data = await this.client.post(path, {
660
+ requests: chunk.tasks.map((task) => task.request),
661
+ concurrency: serverConcurrency
662
+ });
663
+ if (!Array.isArray(data.results) || data.results.length !== chunk.tasks.length) {
664
+ throw new Error(`${path} batch returned an invalid result count`);
665
+ }
666
+ if (data.results.some((row, index) => row.index !== index)) {
667
+ throw new Error(`${path} batch returned results out of order`);
668
+ }
669
+ return data.results;
670
+ }, { concurrency: chunkConcurrency });
671
+ const uniqueResults = new Array(uniqueTasks.length);
672
+ for (const chunkResult of chunkBatch.results) {
673
+ const chunk = chunks[chunkResult.index];
674
+ if (!chunkResult.success || !chunkResult.data) {
675
+ for (let index = 0; index < chunk.tasks.length; index += 1) {
676
+ uniqueResults[chunk.offset + index] = {
677
+ index: chunk.tasks[index].index,
678
+ success: false,
679
+ error: chunkResult.error || `${path} batch request failed`
680
+ };
681
+ }
682
+ continue;
683
+ }
684
+ for (let index = 0; index < chunkResult.data.length; index += 1) {
685
+ const raw = chunkResult.data[index];
686
+ uniqueResults[chunk.offset + index] = {
687
+ index: chunk.tasks[index].index,
688
+ success: raw.success !== false,
689
+ raw,
690
+ error: raw.success === false ? raw.error || raw.message || raw.error_code || `${path} item failed` : void 0
691
+ };
692
+ }
693
+ }
694
+ return tasks.map((task, index) => ({
695
+ ...uniqueResults[deduplicated.sourceIndexByInput[index]],
696
+ index: task.index
697
+ }));
698
+ }
661
699
  async listTools() {
662
700
  const result = await this.client.mcp("tools/list");
663
701
  return result.tools ?? [];
@@ -673,6 +711,188 @@ var Signaliz = class {
673
711
  function compact(input) {
674
712
  return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
675
713
  }
714
+ function findEmailRequestBody(params) {
715
+ return compact({
716
+ company_domain: params.companyDomain,
717
+ full_name: params.fullName,
718
+ first_name: params.firstName,
719
+ last_name: params.lastName,
720
+ linkedin_url: params.linkedinUrl,
721
+ company_name: params.companyName,
722
+ skip_cache: params.skipCache
723
+ });
724
+ }
725
+ function normalizeFindEmailResult(data) {
726
+ const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
727
+ const found = Boolean(email) && data.found !== false;
728
+ const verificationStatus = data.verification_status ?? data.status ?? "unknown";
729
+ const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
730
+ const verificationFreshness = rawFreshness === "fresh" || rawFreshness === "stale" ? rawFreshness : "unknown";
731
+ const needsReverification = data.needs_reverification === true || verificationFreshness === "stale";
732
+ const explicitlyNotSendSafe = data.verified_for_sending === false || needsReverification;
733
+ const verified = !explicitlyNotSendSafe && (data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
734
+ const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
735
+ return {
736
+ success: data.success !== false && found,
737
+ found,
738
+ email,
739
+ firstName: data.first_name,
740
+ lastName: data.last_name,
741
+ confidence: data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
742
+ verificationStatus,
743
+ isVerified: verified,
744
+ isVerifiedForSending: !needsReverification && data.verified_for_sending === true,
745
+ isCatchAll: data.email_is_catch_all === true || data.is_catch_all === true,
746
+ verificationFreshness,
747
+ verificationAgeDays,
748
+ verifiedAt: typeof data.verified_at === "string" ? data.verified_at : null,
749
+ needsReverification,
750
+ providerUsed: data.provider_used ?? data.provider ?? data.email_source ?? data.source ?? "unknown",
751
+ error: found ? void 0 : data.error ?? "No verified email found",
752
+ errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
753
+ raw: data
754
+ };
755
+ }
756
+ function normalizeVerifyEmailResult(email, data) {
757
+ const verificationStatus = String(data.verification_status ?? "").toLowerCase();
758
+ const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
759
+ return {
760
+ email: data.email ?? email,
761
+ isValid: data.is_valid ?? data.valid ?? verified,
762
+ isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
763
+ isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
764
+ confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
765
+ provider: data.provider,
766
+ verificationSource: data.verification_source,
767
+ raw: data
768
+ };
769
+ }
770
+ function companySignalRequestBody(params) {
771
+ const online = params.online ?? true;
772
+ return compact({
773
+ signal_run_id: params.signalRunId,
774
+ company_domain: params.companyDomain,
775
+ company_name: params.companyName,
776
+ research_prompt: params.researchPrompt,
777
+ signal_types: params.signalTypes,
778
+ target_signal_count: params.targetSignalCount,
779
+ lookback_days: params.lookbackDays,
780
+ online,
781
+ enable_deep_search: params.enableDeepSearch ?? online,
782
+ enable_outreach_intelligence: params.enableOutreachIntelligence,
783
+ enable_predictive_intelligence: params.enablePredictiveIntelligence,
784
+ skip_cache: params.skipCache,
785
+ // REST always returns a resumable run instead of holding the connection;
786
+ // waitForResult controls the SDK polling loop.
787
+ wait_for_result: false,
788
+ max_wait_ms: params.maxWaitMs
789
+ });
790
+ }
791
+ function normalizeCompanySignalResult(params, data) {
792
+ return {
793
+ success: data.success ?? true,
794
+ status: data.status,
795
+ signalRunId: data.signal_run_id ?? data.run_id,
796
+ company: {
797
+ name: data.company?.name ?? params.companyName ?? null,
798
+ domain: data.company?.domain ?? params.companyDomain ?? null
799
+ },
800
+ signals: (data.signals ?? []).map((signal) => {
801
+ const metadata = signal.metadata && typeof signal.metadata === "object" && !Array.isArray(signal.metadata) ? signal.metadata : void 0;
802
+ return {
803
+ id: signal.id,
804
+ title: signal.title ?? "",
805
+ type: signal.type ?? signal.signal_type ?? "unknown",
806
+ content: signal.content ?? signal.description ?? "",
807
+ date: signal.date ?? signal.detected_at ?? null,
808
+ datePrecision: signal.date_precision,
809
+ sourceUrl: signal.source_url ?? signal.url ?? null,
810
+ sourceType: signal.source_type,
811
+ sourceProvenance: signal.source_provenance,
812
+ confidence: signal.confidence ?? signal.confidence_score ?? null,
813
+ entityConfidence: signal.entity_confidence ?? metadata?.entity_confidence ?? null,
814
+ signalFamily: signal.signal_family,
815
+ eventType: signal.signal_event_type,
816
+ eventLabel: signal.signal_event_label,
817
+ classification: signal.signal_classification ?? null,
818
+ derived: signal.derived === true,
819
+ evidencePublishedDate: signal.evidence_published_date ?? metadata?.evidence_published_date ?? null,
820
+ signalFeedSource: signal.signal_feed_source ?? metadata?.signal_feed_source,
821
+ metadata
822
+ };
823
+ }),
824
+ signalCount: data.signal_count ?? data.total_signals ?? data.signals?.length ?? 0,
825
+ intelligence: data.intelligence ?? null,
826
+ credits: data.credits,
827
+ metadata: data.metadata,
828
+ raw: data
829
+ };
830
+ }
831
+ function validateBatchSize(items) {
832
+ if (!Array.isArray(items) || items.length === 0) {
833
+ throw new Error("Signaliz batch requests require at least one item");
834
+ }
835
+ if (items.length > 5e3) {
836
+ throw new Error(`Signaliz batch requests support at most 5,000 items; received ${items.length}`);
837
+ }
838
+ }
839
+ function validatedBatchConcurrency(options) {
840
+ const concurrency = options?.concurrency ?? 10;
841
+ if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > 50) {
842
+ throw new Error("Signaliz batch concurrency must be an integer between 1 and 50");
843
+ }
844
+ return concurrency;
845
+ }
846
+ function batchConcurrencyPlan(options) {
847
+ const concurrency = validatedBatchConcurrency(options);
848
+ const serverConcurrency = Math.min(10, concurrency);
849
+ return {
850
+ serverConcurrency,
851
+ chunkConcurrency: Math.max(1, Math.floor(concurrency / serverConcurrency))
852
+ };
853
+ }
854
+ function dedupeExactBatchItems(items, keyForItem) {
855
+ const uniqueItems = [];
856
+ const sourceIndexByInput = [];
857
+ const uniqueIndexByKey = /* @__PURE__ */ new Map();
858
+ for (const item of items) {
859
+ const key = keyForItem(item);
860
+ let uniqueIndex = uniqueIndexByKey.get(key);
861
+ if (uniqueIndex === void 0) {
862
+ uniqueIndex = uniqueItems.length;
863
+ uniqueIndexByKey.set(key, uniqueIndex);
864
+ uniqueItems.push(item);
865
+ }
866
+ sourceIndexByInput.push(uniqueIndex);
867
+ }
868
+ return { uniqueItems, sourceIndexByInput };
869
+ }
870
+ function finalizeCoreBatch(total, startedAt, round, normalize) {
871
+ const results = new Array(total);
872
+ for (const item of round) {
873
+ if (!item.success || !item.raw) {
874
+ results[item.index] = { index: item.index, success: false, error: item.error || "Signaliz batch item failed" };
875
+ continue;
876
+ }
877
+ try {
878
+ results[item.index] = { index: item.index, success: true, data: normalize(item) };
879
+ } catch (error) {
880
+ results[item.index] = {
881
+ index: item.index,
882
+ success: false,
883
+ error: error instanceof Error ? error.message : String(error)
884
+ };
885
+ }
886
+ }
887
+ const succeeded = results.filter((item) => item.success).length;
888
+ return {
889
+ total,
890
+ succeeded,
891
+ failed: total - succeeded,
892
+ durationMs: Date.now() - startedAt,
893
+ results
894
+ };
895
+ }
676
896
  function signalToCopyRequestBody(params) {
677
897
  return compact({
678
898
  company_domain: params.companyDomain,
@@ -734,16 +954,8 @@ function sleep2(ms) {
734
954
  return new Promise((resolve) => setTimeout(resolve, ms));
735
955
  }
736
956
  async function runBatch(items, execute, options) {
737
- if (!Array.isArray(items) || items.length === 0) {
738
- throw new Error("Signaliz batch requests require at least one item");
739
- }
740
- if (items.length > 5e3) {
741
- throw new Error(`Signaliz batch requests support at most 5,000 items; received ${items.length}`);
742
- }
743
- const concurrency = options?.concurrency ?? 10;
744
- if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > 50) {
745
- throw new Error("Signaliz batch concurrency must be an integer between 1 and 50");
746
- }
957
+ validateBatchSize(items);
958
+ const concurrency = validatedBatchConcurrency(options);
747
959
  const startedAt = Date.now();
748
960
  const results = new Array(items.length);
749
961
  let nextIndex = 0;
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  Signaliz,
3
3
  SignalizError
4
- } from "./chunk-R4DIAP7P.mjs";
4
+ } from "./chunk-P3ICLKAE.mjs";
5
5
  export {
6
6
  Signaliz,
7
7
  SignalizError