Skip to content

typescript: root a package's published API from package.json, and bind an arrow under as (#847) - #1621

Merged
swapnilpaliwal-sd merged 1 commit into
0.1.4from
loop/ty-is847
Sep 28, 2026
Merged

swapnilpaliwal-sd merged 1 commit into
0.1.4from
loop/ty-is847

Conversation

@swapnilpaliwal-sd

Copy link
Copy Markdown
Contributor

Closes #847

What was still broken

Roots for tests, HTTP handlers, decorators and exported_from_entry_module exist on 0.1.4. What remained of cause 1 was that TypeScript never read package.json. A library whose index.ts is imported by its own tests is not an "unimported module", so nothing rooted its public API. That API is the code a consumer outside the repository calls, so it read as unreachable, and unreachable reads as safe to delete.

A second gap showed up on a real state-management library. Its main API is written export const createStore = ((createState) => …) as CreateStore. The as blocked the variable→arrow link, so the arrow was neither a call target of createStore(...) nor the thing createStore exports.

Change

  • parser: a new relation, ts_package_entry, the same shape as js_package_entry.
    • It reuses the JS packageEntriesOf walk and adds types and source.
    • Each build-output target (dist/cjs/index.js, esm/index.mjs, dist/index.d.ts) is mapped back to the walked source module. Outcomes: RESOLVED, RESOLVED_FROM_BUILD_OUTPUT, RESOLVED_FROM_PATTERN.
    • A single-* subpath pattern is expanded one path segment at a time, with src/ tried first. This is deliberately narrower than Node, where * can span /.
    • Only package.json files at or under the program root are read.
  • engine: projections/packages.dl and a new entry_point kind, package_export, in config-resolution/entry-points.dl.
    • It roots named METHOD exports, and exported variables bound to a function (var_bound_function), of published modules that are not already entry modules.
    • DEFAULT_INDEX entries and entries with no module hash are declined.
  • parser: const f = ((x) => …) as F now binds the arrow to f, as a bare arrow already did. The same holds under satisfies, <T>, ! and parentheses. The compiler oracle's labelOf names it the same way.
  • Schema, decls, templates, the column-order baseline and SCHEMA.md are updated. The stale "NOT COVERED YET" notes in entry-points.dl are corrected.

Tests

  • Golden case 77-package-published-entries covers a build-output main/exports entry, a ./vanilla subpath, a ./plugins/* pattern, an exported arrow and an arrow under as.
  • Controls in the same case, each of which must stay unrooted:
    • internal.ts: imported, but named by no entry.
    • a blocked ./internal/*.
    • plugins/deep/tracer.ts: two segments under a one-segment *.
    • DEFAULT_INITIAL and castInitial: values, not functions, including one under as.
  • graph/test/typescript/run-tests.sh --oracle: passed 77, failed 0. Case 77 scores oracle=7, engine=8, agree=7, missing=0.
    • The one extra is the function-type signature in the as clause. It is the existing multi-target behaviour for a call through a variable whose declared type is a function type, not a new edge kind.
  • graph/test/javascript/run-tests.sh --oracle: passed 68, failed 0. It is affected through the shared package-json resolver and oracle.
  • parser suites (npx tsx src/test/{typescript,javascript,csharp,gradle,discovery}-tests.ts): all pass. TypeScript is 47/47, including the column-order gate.

Real projects (before → after)

methods call edges entry_reachable package_export roots wall
a real state-management library 1567 1113 → 1294 (+181, 0 lost) 420 → 432 0 → 14 6.3s
a real immutable-update library (control) 487 521 → 521 181 → 181 0 → 13 10.1s
  • All 181 new edges on the state-management library go into the as-wrapped createStore / create / createWithEqualityFn arrows. They are calls from its tests that now resolve.
  • On the immutable-update library, the 13 new roots were already reached through its tests, so its edges and reach are unchanged.

…d an arrow under `as` (#847)

A library whose index.ts is imported by its own tests had no root for its public
API: TypeScript never read package.json, so everything a consumer outside the
repository calls read as unreachable, which reads as safe to delete.

- parser: new relation ts_package_entry (same shape as js_package_entry). It reads
  main, module, exports, types and source, maps each build-output target
  (dist/cjs/index.js, esm/index.mjs, dist/index.d.ts) back to the walked source
  module, and expands a single-`*` subpath pattern one path segment at a time.
  Only package.json files at or under the program root are read.
- engine: projections/packages.dl and a new entry_point kind `package_export`:
  named METHOD exports, and exported variables bound to a function, of published
  modules that are not already entry modules. DEFAULT_INDEX and unresolved
  entries are declined.
- parser: `const f = ((x) => ...) as F` (also satisfies, <T>, !, parentheses)
  now binds the arrow to `f`, as a bare arrow already did. The compiler oracle's
  labelOf names it the same way.

Golden case 77 covers build-output, subpath and pattern entries, with controls:
an imported but unpublished module, a blocked `./internal/*`, a two-segment path
under a one-segment pattern, and a value (plain and under `as`) that roots nothing.

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@swapnilpaliwal-sd
swapnilpaliwal-sd merged commit 44bf73b into 0.1.4 Sep 28, 2026
10 of 11 checks passed
@swapnilpaliwal-sd
swapnilpaliwal-sd deleted the loop/ty-is847 branch September 28, 2026 08:31
swapnilpaliwal-sd added a commit that referenced this pull request Sep 28, 2026
swapnilpaliwal-sd added a commit that referenced this pull request Sep 28, 2026
The vendored parser keeps its own version and moves once per release, only
when parser code changed. dev and main ship it at 0.1.1. On 0.1.4, four
merged changes touched parser/: #1592 (a concise arrow body is owned by the
arrow), #1616 (generated-output detection), #1621 (a package's published API
is rooted from package.json) and #1625 (the Java walk and build directories).
So 0.1.2, one bump for the release.

(cherry picked from commit 51c5e8e)

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
swapnilpaliwal-sd added a commit that referenced this pull request Sep 28, 2026
The vendored parser keeps its own version and moves once per release, only
when parser code changed. dev and main ship it at 0.1.1. On 0.1.4, four
merged changes touched parser/: #1592 (a concise arrow body is owned by the
arrow), #1616 (generated-output detection), #1621 (a package's published API
is rooted from package.json) and #1625 (the Java walk and build directories).
So 0.1.2, one bump for the release.

(cherry picked from commit 51c5e8e)

Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
qtwang pushed a commit to qtwang/axiomcodegraph that referenced this pull request Oct 11, 2026
The vendored parser keeps its own version and moves once per release, only
when parser code changed. dev and main ship it at 0.1.1. On 0.1.4, four
merged changes touched parser/: AxiomCodeAI#1592 (a concise arrow body is owned by the
arrow), AxiomCodeAI#1616 (generated-output detection), AxiomCodeAI#1621 (a package's published API
is rooted from package.json) and AxiomCodeAI#1625 (the Java walk and build directories).
So 0.1.2, one bump for the release.
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.

1 participant