salesprompter-cli 0.1.58 → 0.1.59

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.
Files changed (2) hide show
  1. package/dist/cli.js +110 -76
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -8752,101 +8752,135 @@ async function fetchCompleteLocalSalesNavigatorPeople(sourceQueryUrl, requestHea
8752
8752
  const dimensions = localPeopleSplitDimensions(root.sourceQueryUrl);
8753
8753
  const queue = [root];
8754
8754
  const queuedUrls = new Set([root.slicedQueryUrl]);
8755
+ const rootRecoveryDimensionKeys = new Set();
8755
8756
  const peopleByKey = new Map();
8756
8757
  const slices = [];
8757
8758
  let rootTotalResults = null;
8758
8759
  let fetchedPages = 0;
8759
8760
  let totalDelayMs = 0;
8760
8761
  let retryCount = 0;
8761
- while (queue.length > 0) {
8762
- const attempt = queue.shift();
8763
- const parsedRequest = {
8764
- url: buildSalesNavigatorLeadApiUrlFromSearchUrl(attempt.slicedQueryUrl, options.pageSize),
8765
- headers: requestHeaders,
8766
- };
8767
- let collected = null;
8768
- let tooBroadTotal = null;
8769
- let probeFetchedPages = 0;
8770
- try {
8771
- collected = await fetchAllLocalSalesNavigatorPeople(parsedRequest, {
8772
- requestedProfiles: options.maxResultsPerSearch,
8773
- maxAllowedResults: options.maxResultsPerSearch,
8774
- pageSize: options.pageSize,
8775
- pageDelayMinMs: options.pageDelayMinMs,
8776
- pageDelayMaxMs: options.pageDelayMaxMs,
8777
- retry: options.retry,
8778
- executeRequest: options.executeRequest,
8779
- });
8780
- fetchedPages += collected.fetchedPages;
8781
- totalDelayMs += collected.pacing.totalDelayMs;
8782
- retryCount += collected.pacing.retryCount;
8783
- if (attempt.depth === 0) {
8784
- rootTotalResults = collected.totalResults;
8785
- }
8786
- }
8787
- catch (error) {
8788
- if (!(error instanceof SalesNavigatorSliceTooBroadError)) {
8789
- throw error;
8762
+ while (true) {
8763
+ while (queue.length > 0) {
8764
+ const attempt = queue.shift();
8765
+ const parsedRequest = {
8766
+ url: buildSalesNavigatorLeadApiUrlFromSearchUrl(attempt.slicedQueryUrl, options.pageSize),
8767
+ headers: requestHeaders,
8768
+ };
8769
+ let collected = null;
8770
+ let tooBroadTotal = null;
8771
+ let probeFetchedPages = 0;
8772
+ try {
8773
+ collected = await fetchAllLocalSalesNavigatorPeople(parsedRequest, {
8774
+ requestedProfiles: options.maxResultsPerSearch,
8775
+ maxAllowedResults: options.maxResultsPerSearch,
8776
+ pageSize: options.pageSize,
8777
+ pageDelayMinMs: options.pageDelayMinMs,
8778
+ pageDelayMaxMs: options.pageDelayMaxMs,
8779
+ retry: options.retry,
8780
+ executeRequest: options.executeRequest,
8781
+ });
8782
+ fetchedPages += collected.fetchedPages;
8783
+ totalDelayMs += collected.pacing.totalDelayMs;
8784
+ retryCount += collected.pacing.retryCount;
8785
+ if (attempt.depth === 0) {
8786
+ rootTotalResults = collected.totalResults;
8787
+ }
8790
8788
  }
8791
- tooBroadTotal = error.totalResults;
8792
- const details = error.details && typeof error.details === "object"
8793
- ? error.details
8794
- : {};
8795
- probeFetchedPages = Number(details.fetchedPages ?? 1);
8796
- fetchedPages += probeFetchedPages;
8797
- retryCount += Number(details.retryCount ?? 0);
8798
- totalDelayMs += Number(details.totalDelayMs ?? 0);
8799
- if (attempt.depth === 0) {
8800
- rootTotalResults = tooBroadTotal;
8789
+ catch (error) {
8790
+ if (!(error instanceof SalesNavigatorSliceTooBroadError)) {
8791
+ throw error;
8792
+ }
8793
+ tooBroadTotal = error.totalResults;
8794
+ const details = error.details && typeof error.details === "object"
8795
+ ? error.details
8796
+ : {};
8797
+ probeFetchedPages = Number(details.fetchedPages ?? 1);
8798
+ fetchedPages += probeFetchedPages;
8799
+ retryCount += Number(details.retryCount ?? 0);
8800
+ totalDelayMs += Number(details.totalDelayMs ?? 0);
8801
+ if (attempt.depth === 0) {
8802
+ rootTotalResults = tooBroadTotal;
8803
+ }
8801
8804
  }
8802
- }
8803
- const needsSplit = tooBroadTotal != null ||
8804
- (collected?.totalResults == null &&
8805
- collected != null &&
8806
- collected.people.length >= options.maxResultsPerSearch) ||
8807
- (collected?.totalResults != null &&
8808
- collected.people.length < collected.totalResults);
8809
- if (needsSplit) {
8810
- const usedDimensionKeys = new Set(attempt.splitTrail.map((entry) => entry.key.replace(/-residual$/, "")));
8811
- const nextDimension = dimensions.find((dimension) => !usedDimensionKeys.has(dimension.key));
8812
- if (!nextDimension) {
8813
- throw new Error(`Sales Navigator search still exceeds the ${options.maxResultsPerSearch}-person window after all safe split dimensions were used. Narrow the source search further.`);
8805
+ const needsSplit = tooBroadTotal != null ||
8806
+ (collected?.totalResults == null &&
8807
+ collected != null &&
8808
+ collected.people.length >= options.maxResultsPerSearch) ||
8809
+ (attempt.depth === 0 &&
8810
+ collected?.totalResults != null &&
8811
+ collected.people.length < collected.totalResults);
8812
+ if (needsSplit) {
8813
+ const usedDimensionKeys = new Set(attempt.splitTrail.map((entry) => entry.key.replace(/-residual$/, "")));
8814
+ const nextDimension = dimensions.find((dimension) => !usedDimensionKeys.has(dimension.key));
8815
+ if (!nextDimension) {
8816
+ throw new Error(`Sales Navigator search could not be completed within the ${options.maxResultsPerSearch}-person window after all safe split dimensions were used. Narrow the source search further.`);
8817
+ }
8818
+ if (attempt.depth === 0) {
8819
+ rootRecoveryDimensionKeys.add(nextDimension.key);
8820
+ }
8821
+ const children = expandSalesNavigatorCrawlAttempt(attempt, nextDimension, "people");
8822
+ if (nextDimension.supportsResidualExclusion !== false) {
8823
+ children.push(buildSalesNavigatorResidualCrawlAttempt(attempt, nextDimension, "people"));
8824
+ }
8825
+ for (const child of children) {
8826
+ if (queuedUrls.has(child.slicedQueryUrl))
8827
+ continue;
8828
+ queuedUrls.add(child.slicedQueryUrl);
8829
+ queue.push(child);
8830
+ }
8831
+ slices.push({
8832
+ depth: attempt.depth,
8833
+ splitTrail: attempt.splitTrail,
8834
+ totalResults: tooBroadTotal ?? collected?.totalResults ?? null,
8835
+ collected: 0,
8836
+ fetchedPages: probeFetchedPages || collected?.fetchedPages || 0,
8837
+ status: "split",
8838
+ splitDimension: nextDimension.key,
8839
+ });
8840
+ continue;
8814
8841
  }
8815
- const children = expandSalesNavigatorCrawlAttempt(attempt, nextDimension, "people");
8816
- if (nextDimension.supportsResidualExclusion !== false) {
8817
- children.push(buildSalesNavigatorResidualCrawlAttempt(attempt, nextDimension, "people"));
8842
+ if (!collected) {
8843
+ throw new Error("Sales Navigator slice did not return a collection result.");
8818
8844
  }
8819
- for (const child of children) {
8820
- if (queuedUrls.has(child.slicedQueryUrl))
8821
- continue;
8822
- queuedUrls.add(child.slicedQueryUrl);
8823
- queue.push(child);
8845
+ for (const person of collected.people) {
8846
+ peopleByKey.set(canonicalLocalSalesNavigatorLeadKey(person), person);
8824
8847
  }
8825
8848
  slices.push({
8826
8849
  depth: attempt.depth,
8827
8850
  splitTrail: attempt.splitTrail,
8828
- totalResults: tooBroadTotal ?? collected?.totalResults ?? null,
8829
- collected: 0,
8830
- fetchedPages: probeFetchedPages || collected?.fetchedPages || 0,
8831
- status: "split",
8832
- splitDimension: nextDimension.key,
8851
+ totalResults: collected.totalResults,
8852
+ collected: collected.people.length,
8853
+ fetchedPages: collected.fetchedPages,
8854
+ status: "collected",
8855
+ splitDimension: null,
8833
8856
  });
8834
- continue;
8835
8857
  }
8836
- if (!collected) {
8837
- throw new Error("Sales Navigator slice did not return a collection result.");
8858
+ if (rootTotalResults == null || peopleByKey.size >= rootTotalResults) {
8859
+ break;
8860
+ }
8861
+ const nextRecoveryDimension = dimensions.find((dimension) => !rootRecoveryDimensionKeys.has(dimension.key));
8862
+ if (!nextRecoveryDimension) {
8863
+ break;
8838
8864
  }
8839
- for (const person of collected.people) {
8840
- peopleByKey.set(canonicalLocalSalesNavigatorLeadKey(person), person);
8865
+ rootRecoveryDimensionKeys.add(nextRecoveryDimension.key);
8866
+ const recoveryChildren = expandSalesNavigatorCrawlAttempt(root, nextRecoveryDimension, "people");
8867
+ if (nextRecoveryDimension.supportsResidualExclusion !== false) {
8868
+ recoveryChildren.push(buildSalesNavigatorResidualCrawlAttempt(root, nextRecoveryDimension, "people"));
8869
+ }
8870
+ for (const child of recoveryChildren) {
8871
+ if (queuedUrls.has(child.slicedQueryUrl))
8872
+ continue;
8873
+ queuedUrls.add(child.slicedQueryUrl);
8874
+ queue.push(child);
8841
8875
  }
8842
8876
  slices.push({
8843
- depth: attempt.depth,
8844
- splitTrail: attempt.splitTrail,
8845
- totalResults: collected.totalResults,
8846
- collected: collected.people.length,
8847
- fetchedPages: collected.fetchedPages,
8848
- status: "collected",
8849
- splitDimension: null,
8877
+ depth: 0,
8878
+ splitTrail: [],
8879
+ totalResults: rootTotalResults,
8880
+ collected: 0,
8881
+ fetchedPages: 0,
8882
+ status: "split",
8883
+ splitDimension: nextRecoveryDimension.key,
8850
8884
  });
8851
8885
  }
8852
8886
  const people = [...peopleByKey.values()];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "salesprompter-cli",
3
- "version": "0.1.58",
3
+ "version": "0.1.59",
4
4
  "description": "Sales workflow CLI for guided lead generation, enrichment, scoring, and sync.",
5
5
  "author": "Daniel Sinewe <hello@danielsinewe.com>",
6
6
  "type": "module",