@suss/extractor 0.26.0 → 0.28.0

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.cjs CHANGED
@@ -673,9 +673,12 @@ function composeWrappers(summaries, options = {}) {
673
673
  const byKey = /* @__PURE__ */ new Map();
674
674
  for (const summary of summaries) {
675
675
  const key = summaryKey(summary.location.file, summary.identity.name);
676
- if (!byKey.has(key)) {
677
- byKey.set(key, summary);
676
+ const sharing = byKey.get(key);
677
+ if (sharing === void 0) {
678
+ byKey.set(key, [summary]);
679
+ continue;
678
680
  }
681
+ sharing.push(summary);
679
682
  }
680
683
  const keepGaps = options.gapHandling !== "silent";
681
684
  return summaries.map((summary) => composeOne(summary, byKey, keepGaps));
@@ -683,6 +686,13 @@ function composeWrappers(summaries, options = {}) {
683
686
  function summaryKey(file, name) {
684
687
  return `${file}::${name}`;
685
688
  }
689
+ function summaryOf(reference, byKey) {
690
+ const sharing = byKey.get(summaryKey(reference.file, reference.name)) ?? [];
691
+ if (reference.line === void 0) {
692
+ return sharing[0];
693
+ }
694
+ return sharing.find((one) => one.location.range.start === reference.line) ?? sharing[0];
695
+ }
686
696
  function composeOne(summary, byKey, keepGaps) {
687
697
  const recorded = (0, import_behavioral_ir3.readWrapperMetadata)(summary);
688
698
  const applied = recorded?.applied ?? [];
@@ -696,7 +706,7 @@ function composeOne(summary, byKey, keepGaps) {
696
706
  })
697
707
  };
698
708
  const wrappers = covering.flatMap((reference) => {
699
- const found = byKey.get(summaryKey(reference.file, reference.name));
709
+ const found = summaryOf(reference, byKey);
700
710
  return found === void 0 ? [] : [{ reference, summary: found }];
701
711
  });
702
712
  if (wrappers.length === 0) {
@@ -776,8 +786,8 @@ function applyWrapper(wrapper, inner) {
776
786
  wrapper.summary.transitions.filter((t) => t.output.type !== "delegate"),
777
787
  wrapper.reference
778
788
  );
779
- const passThroughs = wrapper.summary.transitions.filter(
780
- (t) => t.output.type === "delegate"
789
+ const passThroughs = withoutCoveredPassThroughs(
790
+ wrapper.summary.transitions.filter((t) => t.output.type === "delegate")
781
791
  );
782
792
  if (passThroughs.length === 0 || shortCircuits.length + passThroughs.length * inner.transitions.length > MAX_PATHS) {
783
793
  return {
@@ -790,6 +800,20 @@ function applyWrapper(wrapper, inner) {
790
800
  );
791
801
  return { transitions: [...shortCircuits, ...continued], degraded: false };
792
802
  }
803
+ function withoutCoveredPassThroughs(passThroughs) {
804
+ return passThroughs.filter(
805
+ (candidate, i) => !passThroughs.some(
806
+ (other, j) => j !== i && covers(other, candidate) && (j < i || !covers(candidate, other))
807
+ )
808
+ );
809
+ }
810
+ function covers(wider, narrower) {
811
+ if (JSON.stringify(wider.effects) !== JSON.stringify(narrower.effects)) {
812
+ return false;
813
+ }
814
+ const required = new Set(narrower.conditions.map((c) => JSON.stringify(c)));
815
+ return wider.conditions.every((c) => required.has(JSON.stringify(c)));
816
+ }
793
817
  function applyThrowWrapper(wrapper, inner) {
794
818
  const thrown = inner.transitions.filter((t) => t.output.type === "throw");
795
819
  if (thrown.length === 0) {
package/dist/index.d.cts CHANGED
@@ -173,6 +173,12 @@ type DiscoveryMatch = {
173
173
  * `axios.get(...)`.
174
174
  */
175
175
  factoryMethods?: string[];
176
+ /**
177
+ * The import and every instance built from it can be called as a
178
+ * function, so `axios(config)` and `api(config)` are requests the
179
+ * same as a call through a method in `methodFilter`.
180
+ */
181
+ callable?: boolean;
176
182
  } | {
177
183
  /**
178
184
  * A constructor or factory call that takes a configuration object
package/dist/index.d.ts CHANGED
@@ -173,6 +173,12 @@ type DiscoveryMatch = {
173
173
  * `axios.get(...)`.
174
174
  */
175
175
  factoryMethods?: string[];
176
+ /**
177
+ * The import and every instance built from it can be called as a
178
+ * function, so `axios(config)` and `api(config)` are requests the
179
+ * same as a call through a method in `methodFilter`.
180
+ */
181
+ callable?: boolean;
176
182
  } | {
177
183
  /**
178
184
  * A constructor or factory call that takes a configuration object
package/dist/index.js CHANGED
@@ -595,9 +595,12 @@ function composeWrappers(summaries, options = {}) {
595
595
  const byKey = /* @__PURE__ */ new Map();
596
596
  for (const summary of summaries) {
597
597
  const key = summaryKey(summary.location.file, summary.identity.name);
598
- if (!byKey.has(key)) {
599
- byKey.set(key, summary);
598
+ const sharing = byKey.get(key);
599
+ if (sharing === void 0) {
600
+ byKey.set(key, [summary]);
601
+ continue;
600
602
  }
603
+ sharing.push(summary);
601
604
  }
602
605
  const keepGaps = options.gapHandling !== "silent";
603
606
  return summaries.map((summary) => composeOne(summary, byKey, keepGaps));
@@ -605,6 +608,13 @@ function composeWrappers(summaries, options = {}) {
605
608
  function summaryKey(file, name) {
606
609
  return `${file}::${name}`;
607
610
  }
611
+ function summaryOf(reference, byKey) {
612
+ const sharing = byKey.get(summaryKey(reference.file, reference.name)) ?? [];
613
+ if (reference.line === void 0) {
614
+ return sharing[0];
615
+ }
616
+ return sharing.find((one) => one.location.range.start === reference.line) ?? sharing[0];
617
+ }
608
618
  function composeOne(summary, byKey, keepGaps) {
609
619
  const recorded = readWrapperMetadata2(summary);
610
620
  const applied = recorded?.applied ?? [];
@@ -618,7 +628,7 @@ function composeOne(summary, byKey, keepGaps) {
618
628
  })
619
629
  };
620
630
  const wrappers = covering.flatMap((reference) => {
621
- const found = byKey.get(summaryKey(reference.file, reference.name));
631
+ const found = summaryOf(reference, byKey);
622
632
  return found === void 0 ? [] : [{ reference, summary: found }];
623
633
  });
624
634
  if (wrappers.length === 0) {
@@ -698,8 +708,8 @@ function applyWrapper(wrapper, inner) {
698
708
  wrapper.summary.transitions.filter((t) => t.output.type !== "delegate"),
699
709
  wrapper.reference
700
710
  );
701
- const passThroughs = wrapper.summary.transitions.filter(
702
- (t) => t.output.type === "delegate"
711
+ const passThroughs = withoutCoveredPassThroughs(
712
+ wrapper.summary.transitions.filter((t) => t.output.type === "delegate")
703
713
  );
704
714
  if (passThroughs.length === 0 || shortCircuits.length + passThroughs.length * inner.transitions.length > MAX_PATHS) {
705
715
  return {
@@ -712,6 +722,20 @@ function applyWrapper(wrapper, inner) {
712
722
  );
713
723
  return { transitions: [...shortCircuits, ...continued], degraded: false };
714
724
  }
725
+ function withoutCoveredPassThroughs(passThroughs) {
726
+ return passThroughs.filter(
727
+ (candidate, i) => !passThroughs.some(
728
+ (other, j) => j !== i && covers(other, candidate) && (j < i || !covers(candidate, other))
729
+ )
730
+ );
731
+ }
732
+ function covers(wider, narrower) {
733
+ if (JSON.stringify(wider.effects) !== JSON.stringify(narrower.effects)) {
734
+ return false;
735
+ }
736
+ const required = new Set(narrower.conditions.map((c) => JSON.stringify(c)));
737
+ return wider.conditions.every((c) => required.has(JSON.stringify(c)));
738
+ }
715
739
  function applyThrowWrapper(wrapper, inner) {
716
740
  const thrown = inner.transitions.filter((t) => t.output.type === "throw");
717
741
  if (thrown.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/extractor",
3
- "version": "0.26.0",
3
+ "version": "0.28.0",
4
4
  "type": "module",
5
5
  "description": "The suss extraction pipeline, which turns what a language adapter read into the summaries the checker pairs across a boundary.",
6
6
  "keywords": [
@@ -46,7 +46,7 @@
46
46
  "typecheck": "tsc --noEmit"
47
47
  },
48
48
  "dependencies": {
49
- "@suss/behavioral-ir": "0.26.0",
49
+ "@suss/behavioral-ir": "0.28.0",
50
50
  "zod": "^4.0.0"
51
51
  },
52
52
  "devDependencies": {