Skip to content

feat(resolver): phase 8.4 + 8.5 — barrel re-export resolution and CHA/RTA dynamic dispatch#1302

Open
carlos-alm wants to merge 7 commits into
mainfrom
feat/phase-8.4-barrel-reexport-resolution
Open

feat(resolver): phase 8.4 + 8.5 — barrel re-export resolution and CHA/RTA dynamic dispatch#1302
carlos-alm wants to merge 7 commits into
mainfrom
feat/phase-8.4-barrel-reexport-resolution

Conversation

@carlos-alm
Copy link
Copy Markdown
Contributor

@carlos-alm carlos-alm commented Jun 4, 2026

Summary

Phase 8.4: Barrel file re-export chain resolution for call edges

  • The JS/WASM call-edge path (buildImportedNamesMap) was mapping imported symbol names to the barrel file rather than the actual definition file. For example, Button imported from components/index.ts (a barrel) was mapped to components/index.ts instead of components/Button.ts, so resolveCallTargets could not find the node and the call edge was dropped. The native engine already traced through barrels correctly — this PR mirrors that in the WASM/JS fallback path.
  • Fix fix(wasm): barrel-through import edges missing on WASM full builds #1297: Barrel-through import edges (imports kind) were also not emitted on WASM full builds. buildBarrelEdges now uses the same cached barrel resolver, which initialises ctx.barrelExportCache in resolveImports before the edge-building pass.

Phase 8.5: Enhanced dynamic dispatch resolution (CHA + RTA)

Introduces Class Hierarchy Analysis (CHA) and Rapid Type Analysis (RTA) to improve call-graph coverage for OOP codebases.

  • CHA interface dispatch: when a call targets an interface method (e.g. worker.doWork() where worker: IWorker), emit additional calls edges to all known concrete implementations reachable via the class/interface hierarchy — not just the interface declaration.
  • RTA filter: CHA targets are narrowed to types actually instantiated in the program via new X(). Types that are declared but never constructed (e.g. test stubs, dead implementations) are excluded, keeping dispatch fan-out accurate.
  • this/self/super dispatch: inside a method body, this.method() now resolves through the class's own method table and parent hierarchy via qualified-name lookup (ClassName.method), rather than relying on global name matching which misses inherited methods and may produce false positives on name collisions.
  • newExpressions extraction: the JS extractor now captures all new X() constructor names — including unassigned ones like doSomething(new Foo()) — for accurate RTA coverage.

Implementation paths:

  • WASM path: CHA dispatch runs inline in buildFileCallEdges (handles CHA dispatch, this/self/super, and RTA)
  • Native orchestrator path: DB-based CHA expansion post-pass in tryNativeOrchestrator reads implements/extends edges and constructor call evidence from SQLite to expand interface dispatch (known gap: this/super dispatch requires raw unresolved call sites not persisted by the Rust pipeline)
  • Native FFI fallback path: buildChaPostPass in build-edges.ts for when the Rust orchestrator is unavailable

Changes

Phase 8.4:

  • PipelineContext: add barrelExportCache (build-scoped Map) to avoid repeated DFS traversal of reexportMap
  • resolve-imports: export resolveBarrelExportCached; initialise the cache at the start of resolveImports
  • build-edges: apply traceBarrel in buildImportedNamesMap; switch buildBarrelEdges and buildImportedNamesForNative to use resolveBarrelExportCached

Phase 8.5:

  • src/domain/graph/builder/cha.ts (new): ChaContext, buildChaContext, resolveThisDispatch, resolveChaTargets
  • src/types.ts: add newExpressions?: readonly string[] to ExtractorOutput
  • src/extractors/javascript.ts: extractNewExpressionsWalk wired into both extraction paths; fix pre-existing useOptionalChain lint issue
  • src/domain/graph/builder/stages/build-edges.ts: CHA context built before edge transaction; inline CHA dispatch in buildFileCallEdges; buildChaPostPass for native FFI fallback
  • src/domain/graph/builder/stages/native-orchestrator.ts: runPostNativeCha DB-based expansion post-pass

Test plan

  • phase-8.4-barrel-call-resolution.test.ts — call edges resolve through barrel re-exports (wasm + native)
  • phase-8.5-cha-dispatch.test.ts — CHA interface dispatch to ConcreteWorker/MockWorker; RTA excludes GhostWorker; this-dispatch and super-dispatch (wasm only; native gap documented as skipped)
  • issue-1174-chained-barrel-incremental.test.ts:110 — barrel-through import edges on full build (guards fix(wasm): barrel-through import edges missing on WASM full builds #1297)

Closes #1297

…r call edges

The JS/WASM call-edge path (buildImportedNamesMap) was mapping imported
symbol names to the barrel file itself rather than the actual definition
file. For example, `Button` imported from `components/index.ts` (a barrel)
was mapped to `components/index.ts` instead of `components/Button.ts`,
so resolveCallTargets could not find the node and the call edge was dropped.

The native engine already traced through barrels correctly in
buildImportedNamesForNative. This PR mirrors that behavior in the WASM/JS
fallback path and caches results to avoid redundant DFS walks across files.

Changes:
- PipelineContext: add barrelExportCache (build-scoped Map keyed by
  "barrelPath|symbolName") to avoid repeated traversal of the reexportMap
- resolve-imports: export resolveBarrelExportCached, a cache-aware wrapper
  around resolveBarrelExport; reset cache at the start of each build run
- build-edges/buildImportedNamesMap: add barrel tracing via traceBarrel
  helper — matches the logic already in buildImportedNamesForNative
- build-edges: replace all resolveBarrelExport calls with the cached variant
  (emitTypeOnlySymbolEdges, buildBarrelEdges, buildImportedNamesForNative,
  makeContextLookup) for consistency and performance

Also opens #1297 for the pre-existing WASM-only failure where barrel-through
import edges are not emitted on full builds.
The "emits barrel-through edges on full build" assertion in this test
also guards #1297 (barrel-through import edges missing on WASM full
builds). The fix was delivered by the phase 8.4 changes to
buildBarrelEdges — switching to resolveBarrelExportCached which
initialises ctx.barrelExportCache before the edge-building pass.

Closes #1297
@claude
Copy link
Copy Markdown

claude Bot commented Jun 4, 2026

Claude finished @carlos-alm's task —— View job


PR Review: feat(resolver): phase 8.4 — barrel file re-export chain resolution

  • Gather context and understand request
  • Read changed source files
  • Read related context files
  • Analyze root cause and approach
  • Review code quality and test integrity
  • Post final review

Root Cause Analysis

Problem Being Solved: The JS/WASM call-edge path (buildImportedNamesMap) was mapping imported symbol names to the barrel file (e.g. components/index.ts) rather than the actual definition file (components/Button.ts). As a result, resolveCallTargets could not find the node in nodesByNameAndFile and silently dropped the call edge. The native Rust engine already traced through barrel files correctly — this PR closes the parity gap. A second issue (#1297) — barrel-through import edges not emitted on WASM full builds — is also resolved as a side effect of switching buildBarrelEdges to use resolveBarrelExportCached (which ensures ctx.barrelExportCache is initialized before the edge-building pass).

Why This Approach: The fix mirrors the pattern already used in buildImportedNamesForNative (lines 620–625 in build-edges.ts) and adds a build-scoped cache to avoid repeated DFS walks over reexportMap. This is the right approach: it doesn't paper over the symptom — it fixes the data that was fed to resolveCallTargets.

Risk Assessment: Low. The change is purely additive within the existing abstraction. The traceBarrel helper is a thin wrapper around resolveBarrelExportCached, which is itself a thin wrapper around the existing resolveBarrelExport. The cache is reset at the start of every build run (resolveImports.ts:188), so stale entries are impossible between builds.


Phase 2: Configuration Change Detection

No lint rules, TypeScript flags, build configuration, or test thresholds were modified. Clean.


Phase 3: Test Integrity

Tests are strengthening coverage, not weakening it:

  • phase-8.4-barrel-call-resolution.test.ts runs against both wasm and native engines, asserts the positive case (edge lands on leaf file) and the negative case (no edge to the barrel) — both meaningful, neither trivially satisfied.
  • The 3-line addition to issue-1174-chained-barrel-incremental.test.ts only updates the doc-comment to note that the existing assertion also guards fix(wasm): barrel-through import edges missing on WASM full builds #1297. No assertion changes.
  • Fixture is minimal and self-documenting.

Phase 4: Code Quality

resolve-imports.ts:172–183 (resolveBarrelExportCached)

Clean implementation. One minor correctness note: Map<string, string | null> correctly stores null sentinel values to distinguish "looked up and resolved to nothing" from "not yet looked up". The .has() check before .get() prevents the undefined ambiguity. The as string | null cast (commit 27b6054) is safe given the guarded .has(). ✓

build-edges.ts:688–692 (traceBarrel closure)

Matches buildImportedNamesForNative's logic exactly (lines 622–625). The symmetry makes the parity easy to audit. ✓

resolve-imports.ts:188 — cache initialization ordering

ctx.barrelExportCache = new Map() is the first statement in resolveImports (before buildReexportMap and reparseBarrelFiles). Since buildEdges runs after resolveImports, barrelExportCache is always initialized before buildBarrelEdges, buildImportedNamesMap, or emitTypeOnlySymbolEdges are called. The cache never contains stale entries from a prior build because PipelineContext is not reused across buildGraph calls (it's constructed fresh each time). ✓

context.ts:72 — default initialization

barrelExportCache: Map<string, string | null> = new Map() provides a safe empty-map default, ensuring no call site can throw on ctx.barrelExportCache.has() even if resolveImports were somehow skipped. This is belt-and-suspenders and costs nothing. ✓

One observation worth flagging:

buildImportedNamesForNative (lines 607–636) was already tracing through barrels via resolveBarrelExportCached, but it was calling resolveBarrelExport directly (uncached) in the previous version of this file. The PR switches it to the cached variant — this is correct and consistent. All four call sites in build-edges.ts (emitTypeOnlySymbolEdges, buildBarrelEdges, buildImportedNamesForNative, makeContextLookup) now use the cached wrapper. The direct resolveBarrelExport export remains available for callers that carry their own visited set (the recursive DFS), which is correct — the cached wrapper does not expose visited.


Backlog Compliance

  • Zero-dep: ✓ — no new dependencies entries in package.json
  • Foundation-aligned: ✓ — pure local graph improvement; no cloud calls, no external toolchain, no code generation
  • Problem-fit: 5 — directly prevents hallucinated missing call edges. AI agents reading the graph would previously see no edge from render → Button (a real call) and either hallucinate the dependency or miss it entirely. This is the core "lost AI" problem.
  • Breaking: No — purely additive; no API, CLI output format, DB schema, or MCP contract changes
  • Tier: 1

Final Recommendation

Rating: ⭐⭐⭐⭐ (4/5)

Action: APPROVE

Reasoning: The fix is correct, minimal, well-tested, and mirrors the exact pattern already used in the native path. Root cause is properly addressed (not symptom-masked). Both the positive and negative test assertions are meaningful. The 3-commit structure is clean: main feature, minor correctness tweak, documentation. No configuration relaxation, no weakened assertions, no new dependencies.

The one thing keeping this from 5/5 is the absence of a test covering the incremental-build path for this specific fixture (all existing phase-8.4 tests use incremental: false). The issue-1174 test covers the incremental barrel-import path on a different fixture, but a dedicated incremental test for the call-edge case would close the gap. This is a minor omission — the incremental path still runs through buildImportedNamesMap and the cache reset is unconditional — but worth noting.


@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 4, 2026

Greptile Summary

This PR delivers two pipeline improvements: Phase 8.4 fixes barrel re-export resolution in the WASM/JS call-edge path so imported symbols map to their leaf definition file rather than the barrel, and Phase 8.5 introduces Class Hierarchy Analysis (CHA) with Rapid Type Analysis (RTA) filtering to expand interface/abstract method dispatch to all instantiated concrete implementations.

  • Phase 8.4: buildImportedNamesMap now calls resolveBarrelExportCached (a new build-scoped memoized wrapper) to trace through barrel files, matching the existing behaviour of the native path. buildBarrelEdges and buildImportedNamesForNative are similarly updated. propagateReturnTypesAcrossFiles is moved before the transaction definition so the CHA context can be constructed from fully-propagated typeMaps.
  • Phase 8.5 (WASM path): buildChaContext builds an implementors/parents/instantiatedTypes index from all parsed file symbols; inline dispatch in buildFileCallEdges expands this/self/super calls and typed-receiver calls to concrete implementations; extractNewExpressionsWalk feeds the RTA set with all new X() usages including unassigned ones.
  • Phase 8.5 (native paths): buildChaPostPass (native FFI fallback) mirrors the inline path using ctx.fileSymbols; runPostNativeCha (native orchestrator) performs the same expansion via DB queries on implements/extends edges and constructor-call evidence.

Confidence Score: 5/5

Safe to merge; changes are additive and well-tested across both engine paths.

The barrel-resolution fix is a straightforward correctness change with targeted tests. The CHA/RTA implementation is well-structured, correctly handles multi-interface dispatch (extractor emits one ClassRelation per interface), guards against hierarchy cycles, and follows existing patterns for post-pass edge insertion. The two notes in runPostNativeCha (no debug log on empty instantiated set, no explicit transaction around batchInsertEdges) are operational polish issues that do not affect correctness under normal conditions.

src/domain/graph/builder/stages/native-orchestrator.ts — the runPostNativeCha function; silent early-return and non-transactional inserts are worth hardening before this path sees heavy production traffic.

Important Files Changed

Filename Overview
src/domain/graph/builder/cha.ts New CHA + RTA module — correctly handles multi-interface dispatch (extractor emits one ClassRelation per interface), cycle-safe parent-chain walk (visited set, implicit depth cap), and RTA filtering via instantiatedTypes set. EMPTY_CHA_CONTEXT sentinel is clean.
src/domain/graph/builder/stages/build-edges.ts Barrel tracing (8.4) correctly moved into buildImportedNamesMap, buildBarrelEdges, and makeContextLookup. CHA context built before the transaction opens, after propagateReturnTypesAcrossFiles. Inline CHA dispatch in buildFileCallEdges and buildChaPostPass follow existing seenByPair patterns.
src/domain/graph/builder/stages/native-orchestrator.ts runPostNativeCha: silent early-exit when instantiated set is empty (no debug log), and batchInsertEdges is outside any explicit transaction. Role re-classification via dynamic import is correctly scoped to affected files.
src/domain/graph/builder/stages/resolve-imports.ts resolveBarrelExportCached adds a build-scoped memoization layer over resolveBarrelExport; cache is reset at the top of resolveImports so each build starts fresh.
src/extractors/javascript.ts extractNewExpressionsWalk correctly walks the full AST for new_expression nodes in both query and walk paths, including unassigned usages. The useOptionalChain lint fix is a minor correctness improvement.
src/extractors/csharp.ts handleCsObjectCreation now also pushes to newExpressions for RTA parity with the JS extractor.
src/domain/graph/builder/context.ts barrelExportCache added as an eagerly-initialised Map so it is never undefined, even when resolveImports hasn't been called first.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[buildEdges entry] --> B[propagateReturnTypesAcrossFiles]
    B --> C[buildChaContext]
    C --> D{Engine?}
    D -->|WASM / JS| E[buildCallEdgesJS]
    E --> F[buildFileCallEdges inline CHA dispatch]
    F --> F1{receiver type}
    F1 -->|this/self/super| G[resolveThisDispatch]
    F1 -->|typed receiver| H[resolveChaTargets RTA-filtered]
    D -->|Native FFI fallback| I[native engine builds edges]
    I --> J[buildParamFlowPtsPostPass]
    J --> K[buildChaPostPass]
    D -->|Native orchestrator| L[tryNativeOrchestrator]
    L --> M[runPostNativeCha DB query]
    M --> N{chaTargetIds > 0?}
    N -->|yes| O[classifyNodeRoles re-run]
    G --> P[emit CHA calls edges]
    H --> P
    K --> P
    M --> P
Loading

Fix All in Claude Code

Reviews (4): Last reviewed commit: "fix(parity): re-classify roles after CHA..." | Re-trigger Greptile

Comment on lines +75 to +80
const barrelCallEdge = callEdges.find(
(e) =>
e.caller_name === 'render' &&
e.callee_name === 'Button' &&
e.callee_file === 'components/Button.ts',
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The positive assertion doesn't check caller_file, so any render → Button edge from any file would satisfy it. With the current minimal fixture this is unambiguous, but adding a caller_file check future-proofs the test if new render functions appear in the fixture.

Suggested change
const barrelCallEdge = callEdges.find(
(e) =>
e.caller_name === 'render' &&
e.callee_name === 'Button' &&
e.callee_file === 'components/Button.ts',
);
const barrelCallEdge = callEdges.find(
(e) =>
e.caller_name === 'render' &&
e.caller_file === 'App.ts' &&
e.callee_name === 'Button' &&
e.callee_file === 'components/Button.ts',
);

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — added caller_file === 'App.ts' to the assertion so the match is fully specified and won't become ambiguous if new render functions are added to the fixture.

… + RTA)

Introduces Class Hierarchy Analysis (CHA) and Rapid Type Analysis (RTA) to
improve call-graph coverage for OOP codebases.

CHA: when a call targets an interface or abstract method (e.g. worker.doWork()
where worker: IWorker), emit additional call edges to all known concrete
implementations reachable via the class/interface hierarchy.

RTA filter: CHA targets are narrowed to types actually instantiated in the
program via new X() — prevents dead/test-only implementations from inflating
the dispatch fan-out.

this/self/super dispatch: inside a method body, this.method() now resolves
through the class's own method table and parent hierarchy via qualified-name
lookup (e.g. ClassName.method), rather than relying solely on global name
matching which may miss inherited or ambiguous methods.

Implementation:
- src/domain/graph/builder/cha.ts (new): ChaContext, buildChaContext,
  resolveThisDispatch, resolveChaTargets
- ExtractorOutput.newExpressions: dedicated RTA instantiation list extracted
  from all new X() expressions in JS/TS files (not just assigned ones)
- WASM path: CHA dispatch runs inline in buildFileCallEdges
- Native path: DB-based CHA expansion post-pass in tryNativeOrchestrator
  (interface dispatch only; this/super dispatch is a known gap for native)
- build-edges.ts: buildChaPostPass wired for native FFI path (fallback mode)

Test: tests/integration/phase-8.5-cha-dispatch.test.ts covers CHA dispatch,
RTA filter, this-dispatch (wasm only), and super-dispatch (wasm only) across
the cha-dispatch fixture with IWorker/ConcreteWorker/MockWorker/GhostWorker.
@carlos-alm carlos-alm changed the title feat(resolver): phase 8.4 — barrel file re-export chain resolution feat(resolver): phase 8.4 + 8.5 — barrel re-export resolution and CHA/RTA dynamic dispatch Jun 4, 2026
…est assertion (#1302)

- Add caller_file check to the barrel call resolution test assertion to
  future-proof it against fixture growth (greptile review)
- Add comment in propagateReturnTypesAcrossFiles documenting the Phase 8.4
  barrel-tracing side-effect on cross-file return-type propagation
@carlos-alm
Copy link
Copy Markdown
Contributor Author

Addressed both Greptile review points:

  1. caller_file in test assertion — Added e.caller_file === 'App.ts' to the positive assertion in phase-8.4-barrel-call-resolution.test.ts so the match is fully specified.

  2. Undocumented Phase 8.2 side-effect — Added a comment in propagateReturnTypesAcrossFiles documenting that buildImportedNamesMap's barrel tracing (Phase 8.4) also improves cross-file return-type propagation through re-export chains, so future readers don't need to reverse-engineer it.

@carlos-alm
Copy link
Copy Markdown
Contributor Author

@greptileai

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

Codegraph Impact Analysis

32 functions changed24 callers affected across 9 files

  • ChaContext.implementors in src/domain/graph/builder/cha.ts:20 (0 transitive callers)
  • ChaContext.parents in src/domain/graph/builder/cha.ts:22 (0 transitive callers)
  • ChaContext.instantiatedTypes in src/domain/graph/builder/cha.ts:24 (0 transitive callers)
  • buildChaContext in src/domain/graph/builder/cha.ts:39 (3 transitive callers)
  • resolveThisDispatch in src/domain/graph/builder/cha.ts:100 (5 transitive callers)
  • resolveChaTargets in src/domain/graph/builder/cha.ts:138 (5 transitive callers)
  • buildChaPostPass in src/domain/graph/builder/stages/build-edges.ts:623 (3 transitive callers)
  • buildCallEdgesJS in src/domain/graph/builder/stages/build-edges.ts:721 (3 transitive callers)
  • buildFileCallEdges in src/domain/graph/builder/stages/build-edges.ts:860 (3 transitive callers)
  • buildEdges in src/domain/graph/builder/stages/build-edges.ts:1203 (4 transitive callers)
  • runPostNativeCha in src/domain/graph/builder/stages/native-orchestrator.ts:400 (4 transitive callers)
  • tryNativeOrchestrator in src/domain/graph/builder/stages/native-orchestrator.ts:863 (5 transitive callers)
  • extractSymbolsQuery in src/extractors/javascript.ts:314 (1 transitive callers)
  • extractSymbolsWalk in src/extractors/javascript.ts:589 (1 transitive callers)
  • extractNewExpressionsWalk in src/extractors/javascript.ts:1383 (3 transitive callers)
  • walk in src/extractors/javascript.ts:1384 (10 transitive callers)
  • extractCallbackDefinition in src/extractors/javascript.ts:1911 (6 transitive callers)
  • ExtractorOutput.newExpressions in src/types.ts:603 (0 transitive callers)
  • Animal in tests/fixtures/cha-dispatch/Animal.ts:1 (0 transitive callers)
  • Animal.speak in tests/fixtures/cha-dispatch/Animal.ts:2 (0 transitive callers)

…for C# RTA (#1302)

C# extractor never populated newExpressions, so WASM CHA had no RTA seed for
C# instantiated types.  Additionally, newExpressions was stripped during worker
thread serialization (SerializedExtractorOutput lacked the field, and neither
serializeExtractorOutput nor deserializeResult handled it).

- csharp.ts: populate newExpressions in extractCSharpSymbols and push type
  names in handleCsObjectCreation
- wasm-worker-protocol.ts: add newExpressions field to SerializedExtractorOutput
- wasm-worker-entry.ts: include newExpressions in serializeExtractorOutput
- wasm-worker-pool.ts: restore newExpressions in deserializeResult
…1302)

The Rust orchestrator classifies roles as part of its internal pipeline, before
the JS runPostNativeCha post-pass adds CHA call edges.  Implementor methods
(e.g. UserRepository.Save) had no incoming edges at classification time and
were tagged dead-ffi, diverging from the WASM engine which classifies roles
after all edges (including CHA) are inserted.

runPostNativeCha now returns the Set of target node IDs for newly inserted
edges.  tryNativeOrchestrator uses this set to query the affected files and
re-runs classifyNodeRoles (incremental) on those files only, bringing native
and WASM role results into alignment.
@carlos-alm
Copy link
Copy Markdown
Contributor Author

Two additional fixes pushed after investigating a build-parity.test.ts failure that was exposed during CI:

1. C# newExpressions not populated or serialized (cascading bug)

The C# extractor never populated newExpressions, so WASM CHA had no RTA seed for C# instantiated types. Additionally, even after fixing the extractor, newExpressions was being stripped during worker thread serialization — SerializedExtractorOutput lacked the field, and neither serializeExtractorOutput nor deserializeResult handled it. Fixed in four files: csharp.ts, wasm-worker-protocol.ts, wasm-worker-entry.ts, wasm-worker-pool.ts.

2. Native engine roles stale after CHA post-pass

runPostNativeCha runs as a JS post-pass AFTER the Rust orchestrator has already classified roles. Implementor methods (e.g. UserRepository.Save) had no incoming call edges at classification time, so they were tagged dead-ffi — diverging from the WASM engine which classifies roles only after all edges (including CHA) are committed.

Fix: runPostNativeCha now returns the set of target node IDs for newly inserted edges. tryNativeOrchestrator uses this to query the affected files and re-runs classifyNodeRoles (incremental, scoped to those files only) immediately after the CHA edges are inserted.

All 8 build-parity tests now pass (native and WASM produce identical nodes, edges, roles, and ast_nodes for both the JS sample-project and C# fixtures).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(wasm): barrel-through import edges missing on WASM full builds

1 participant