Skip to content

feat: add requestedFields sparse fieldset filtering to both execution engines#81

Merged
aarne merged 8 commits intosparse_fieldsetsfrom
copilot/unify-sparse-fieldsets
Mar 4, 2026
Merged

feat: add requestedFields sparse fieldset filtering to both execution engines#81
aarne merged 8 commits intosparse_fieldsetsfrom
copilot/unify-sparse-fieldsets

Conversation

Copy link
Contributor

Copilot AI commented Mar 4, 2026

Phase 1 of the Sparse Fieldsets architecture. Both executeBridge engines now accept requestedFields?: string[] to resolve only the listed output fields. Unrequested tools are never called (interpreter) or never compiled (compiler).

const { data } = await executeBridge({
  document,
  operation: "Query.searchTrains",
  input: { from: "Bern", to: "Zürich" },
  requestedFields: ["id", "status", "legs.*"],
  tools: { /* ... */ },
});
// → only resolves id, status, legs.* — skips tools that feed other fields

Pattern syntax

Dot-separated paths with optional trailing wildcard: "id", "legs.duration", "legs.*".

Core changes

  • bridge-core/src/requested-fields.ts — new utility: matchesRequestedFields() and filterOutputFields() with exact, ancestor/descendant, and * wildcard matching
  • Interpreter (bridge-core)run() filters output fields before the pull loop; resolveNestedField() also respects the filter for nested sub-fields. Pull-based execution naturally orphans unreachable tools.
  • Compiler (bridge-compiler) — filters output wires at codegen time. Dead code detection upgraded from a flat single-pass scan to backward reachability (transitive closure from output wires through tool input dependencies), so tools only reachable through pruned outputs are eliminated. Cache key includes sorted requestedFields for shape-specific compiled functions.

Tests

20 new shared parity tests (both engines):

  • Tools that only feed unrequested fields throw on invocation → proves they're never called
  • (A || B → C) graph: requesting fromA skips B and C; requesting fromB skips A but calls B with fallback to C
  • Wildcard, multi-field, nested path, and no-filter backward-compat cases

Docs

  • New advanced/sparse-fieldsets.mdx doc page
  • Updated bridge-compiler README

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.open-meteo.com
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA tsc -p tsconfig.json --noEmit && vite build 1/x64/bin/node n/sh tsc -p tsconfig.sh e-core and bridg-c odules/npm/node_pnpm -r e2e node (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA tsc -p tsconfig.INVALID,NEW 1/x64/bin/node n/sh tsc -p tsconfig.sh (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA 2e.test.ts --name-status de/node/bin/node /home/REDACTED/worsh pm/@esbuild+linu-c 1/x64/lib/node_mpnpm -r e2e bash (dns block)
  • dummyjson.com
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA tsc -p tsconfig.INVALID,NEW 1/x64/bin/node n/sh tsc -p tsconfig.sh (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA 2e.test.ts --name-status /usr/bin/cat /home/REDACTED/worsh orkers-types@4.2-c h cat (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA 2e.test.ts te/package.json und/package.json --format=t:%ct --name-status ode-gyp-bin/sh sh (dns block)
  • nominatim.openstreetmap.org
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA tsc -p tsconfig.json --noEmit && vite build 1/x64/bin/node n/sh tsc -p tsconfig.sh e-core and bridg-c odules/npm/node_pnpm -r e2e node (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA tsc -p tsconfig.INVALID,NEW 1/x64/bin/node n/sh tsc -p tsconfig.sh (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA 2e.test.ts --name-status de/node/bin/node /home/REDACTED/worsh pm/@esbuild+linu-c 1/x64/lib/node_mpnpm -r e2e bash (dns block)
  • sparrow.cloudflare.com
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --no-warnings --experimental-vm-modules /home/REDACTED/work/bridge/bridge/node_modules/.pnpm/wrangler@4.69.0_@cloudflare+workers-types@4.20260228.1/node_modules/wrangler/wrangler-dist/cli.js types (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --no-warnings --experimental-vm-modules /home/REDACTED/work/bridge/bridge/node_modules/.pnpm/wrangler@4.69.0_@cloudflare+workers-types@4.20260228.1/node_modules/wrangler/wrangler-dist/cli.js types unset --global dules/.bin/node credential.helpesh (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --no-warnings --experimental-vm-modules /home/REDACTED/work/bridge/bridge/node_modules/.pnpm/wrangler@4.69.0_@cloudflare+workers-types@4.20260228.1/node_modules/wrangler/wrangler-dist/cli.js types build (dns block)
  • telemetry.astro.build
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/bridge/bridge/packages/docs-site/node_modules/.bin/../astro/astro.js build e_modules/@esbuild/linux-x64/bin/esbuild (dns block)
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/bridge/bridge/packages/docs-site/node_modules/.bin/../astro/astro.js build git s/.b�� vite build --global bin/node user.name (dns block)
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/bridge/bridge/packages/docs-site/node_modules/.bin/../astro/astro.js build sed s/.b�� s,\\,/,g (dns block)
  • transport.opendata.ch
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA tsc -p tsconfig.INVALID,NEW 1/x64/bin/node ules/pnpm/dist/nDROP tsc -p tsconfig.sh e-core and bridg-c rgo/bin/git node (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA 2e.test.ts --name-status (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA 2e.test.ts te/package.json und/package.json --format=t:%ct --name-status node_modules/.pnpnpm -r e2e sh (dns block)
  • v6.db.api.bahn.guru
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA tsc -p tsconfig.INVALID,NEW 1/x64/bin/node ules/pnpm/dist/nDROP tsc -p tsconfig.sh e-core and bridg-c rgo/bin/git node (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA 2e.test.ts --name-status (dns block)
    • Triggering command: /opt/hostedtoolcache/node/24.13.1/x64/bin/node /opt/hostedtoolcache/node/24.13.1/x64/bin/node --heap-prof-interval=524288 --cpu-prof-interval=1000 --test-coverage-functions=0 --test-concurrency=0 --inspect-publish-uid=stderr,http --inspect-port=127.0.0.1:9229 --experimental-transform-types --report-signal=SIGUSR2 --test-coverage-lines=0 --test-isolation=process --conditions=source --tls-cipher-list=TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA 2e.test.ts te/package.json und/package.json --format=t:%ct --name-status node_modules/.pnpnpm -r e2e sh (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Unified Sparse Fieldsets & GraphQL Lookahead Architecture</issue_title>
<issue_description>Epic: Core Execution Engine & API Adapters
Status: Planned
Impact: Eliminates the "GraphQL Tax" (N+1 overhead), introduces Dead-Code Elimination to the AOT compiler, and standardizes payload subsetting across REST and GraphQL.

Overview

Currently, the Bridge GraphQL adapter relies on standard recursive field resolvers, which forces the execution engine to fight the GraphQL runner. Meanwhile, the standalone executeBridge fetches the entire .bridge schema graph regardless of what the client actually needs.

This epic unifies both environments by introducing Sparse Fieldsets (requestedFields) to the core engines, and refactoring the GraphQL adapter into a pure "Lookahead" translation layer.


Phase 1: Core Engine Upgrades (executeBridge)

Both @stackables/bridge-core (Interpreter) and @stackables/bridge-compiler (AOT) need to accept a unified syntax for requesting partial data.

  • API Update: Add requestedFields?: string[] to ExecuteBridgeOptions.

  • Glob Syntax: Implement a dot-separated wildcard parser (e.g., ["id", "price", "legs.*"]) to match against output wire paths.

  • Interpreter (bridge-core) implementation: * Filter the initial outputWires against requestedFields before beginning the pull loop.

  • Because the interpreter is pull-based, dropping an output wire automatically orphans the unneeded tools, skipping their execution.

  • Compiler (bridge-compiler) implementation:

  • Filter output wires during code generation.

  • Kahn's Algorithm will mathematically eliminate the dead code (unreachable tools).

  • Update the fnCache WeakMap key to include the sorted requestedFields so different query shapes cache distinct, perfectly sized native functions.


Phase 2: Standalone / REST Integration

Expose the new requestedFields array to standalone consumers, allowing Bridge to power highly efficient REST/RPC endpoints.

  • Documentation Update: Show how to map HTTP query parameters to the engine.

  • Example: GET /api/trains?fields=id,status,legs.duration

  • Handler: executeBridge({ document, operation: "Query.trains", requestedFields: req.query.fields.split(",") })

  • Result: Mobile apps can request lightweight payloads, and desktop apps can request heavy payloads, all routed through the same compiled .bridge file without downstream over-fetching.


Phase 3: The GraphQL Adapter Refactor

Transform @stackables/bridge-graphql from a recursive execution engine into a Root-Level Lookahead Translator. Bridge handles the execution; GraphQL merely handles the schema and validation. GraphQL adapter will accept optional executor.

  • Drop Per-Field Resolvers: Stop generating resolver functions for every nested object/field in the GraphQL schema.
  • Extract Selection Set: Write a recursive helper to parse the 4th argument (GraphQLResolveInfo) in root queries/mutations. Translate info.selectionSet into the flat, dot-separated requestedFields array (e.g., { train { id, status } } ➡️ ["train.id", "train.status"]).
  • Unified Injection: * Inject the requested fields into the injected executor (either Core or Compiler).
  • Bridge executes the exact subset of tools required in a single pass.
  • Return the perfectly shaped JSON directly to the GraphQL engine, which simply passes it through to the client.

</issue_description>

<agent_instructions>Implement phase 1. make sure to include

  • end user docs
  • bridge level lang tests that are run against both engines
    • test has to cover dropping unrequested tool calls
    • test with (A || B -> C) where A is independently wired and C depends on B. each wiring directly or indirectly to output that can be controlled with the test</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@changeset-bot
Copy link

changeset-bot bot commented Mar 4, 2026

🦋 Changeset detected

Latest commit: f194369

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@stackables/bridge-core Minor
@stackables/bridge-compiler Minor
@stackables/bridge-graphql Patch
@stackables/bridge-parser Patch
@stackables/bridge Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@aarne aarne changed the base branch from main to sparse_fieldsets March 4, 2026 13:14
@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

🐰 Bencher Report

Branchcopilot/unify-sparse-fieldsets
Testbedubuntu-latest

⚠️ WARNING: No Threshold found!

Without a Threshold, no Alerts will ever be generated.

Click here to create a new Threshold
For more information, see the Threshold documentation.
To only post results if a Threshold exists, set the --ci-only-thresholds flag.

Click to view all benchmark results
BenchmarkLatencynanoseconds (ns)
compiled: absolute baseline (passthrough, no tools)📈 view plot
⚠️ NO THRESHOLD
0.00 ns
compiled: array + tool-per-element 10📈 view plot
⚠️ NO THRESHOLD
0.01 ns
compiled: array + tool-per-element 100📈 view plot
⚠️ NO THRESHOLD
0.03 ns
compiled: chained 3-tool fan-out📈 view plot
⚠️ NO THRESHOLD
0.00 ns
compiled: flat array 10 items📈 view plot
⚠️ NO THRESHOLD
0.01 ns
compiled: flat array 100 items📈 view plot
⚠️ NO THRESHOLD
0.01 ns
compiled: flat array 1000 items📈 view plot
⚠️ NO THRESHOLD
0.07 ns
compiled: nested array 10x10📈 view plot
⚠️ NO THRESHOLD
0.02 ns
compiled: nested array 20x10📈 view plot
⚠️ NO THRESHOLD
0.04 ns
compiled: nested array 5x5📈 view plot
⚠️ NO THRESHOLD
0.01 ns
compiled: short-circuit (overdefinition bypass)📈 view plot
⚠️ NO THRESHOLD
0.00 ns
compiled: simple chain (1 tool)📈 view plot
⚠️ NO THRESHOLD
0.00 ns
exec: absolute baseline (passthrough, no tools)📈 view plot
⚠️ NO THRESHOLD
0.00 ns
exec: array + tool-per-element 10📈 view plot
⚠️ NO THRESHOLD
0.08 ns
exec: array + tool-per-element 100📈 view plot
⚠️ NO THRESHOLD
0.74 ns
exec: chained 3-tool fan-out📈 view plot
⚠️ NO THRESHOLD
0.02 ns
exec: flat array 10 items📈 view plot
⚠️ NO THRESHOLD
0.01 ns
exec: flat array 100 items📈 view plot
⚠️ NO THRESHOLD
0.07 ns
exec: flat array 1000 items📈 view plot
⚠️ NO THRESHOLD
0.65 ns
exec: nested array 10x10📈 view plot
⚠️ NO THRESHOLD
0.12 ns
exec: nested array 20x10📈 view plot
⚠️ NO THRESHOLD
0.23 ns
exec: nested array 5x5📈 view plot
⚠️ NO THRESHOLD
0.05 ns
exec: short-circuit (overdefinition bypass)📈 view plot
⚠️ NO THRESHOLD
0.00 ns
exec: simple chain (1 tool)📈 view plot
⚠️ NO THRESHOLD
0.01 ns
parse: large bridge (20 handles x 5 wires)📈 view plot
⚠️ NO THRESHOLD
0.92 ns
parse: simple bridge📈 view plot
⚠️ NO THRESHOLD
0.03 ns
🐰 View full continuous benchmarking report in Bencher

…iler engines

- Add requestedFields option to ExecuteBridgeOptions in bridge-core and bridge-compiler
- Implement matchesRequestedFields utility with dot-separated path and wildcard support
- Runtime: filter output fields in ExecutionTree.run() and resolveNestedField()
- Compiler: filter output wires and use backward reachability for dead code elimination
- Update compiler cache key to include sorted requestedFields
- Add 20 shared parity tests covering field filtering, tool skipping, A||B→C chains, wildcards

Co-authored-by: aarne <82001+aarne@users.noreply.github.com>
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 4, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bridge f194369 Commit Preview URL

Branch Preview URL
Mar 04 2026, 02:39 PM

Copilot AI and others added 2 commits March 4, 2026 13:36
Co-authored-by: aarne <82001+aarne@users.noreply.github.com>
Co-authored-by: aarne <82001+aarne@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement unified sparse fieldsets and GraphQL lookahead architecture feat: add requestedFields sparse fieldset filtering to both execution engines Mar 4, 2026
Copilot finished work on behalf of aarne March 4, 2026 13:43
@aarne aarne marked this pull request as ready for review March 4, 2026 13:53
@aarne aarne merged commit b4e25cc into sparse_fieldsets Mar 4, 2026
4 checks passed
@aarne aarne deleted the copilot/unify-sparse-fieldsets branch March 4, 2026 14:39
aarne added a commit that referenced this pull request Mar 4, 2026
* feat: add `requestedFields` sparse fieldset filtering to both execution engines (#81)

* Initial plan

* feat: add requestedFields (sparse fieldsets) to both runtime and compiler engines

- Add requestedFields option to ExecuteBridgeOptions in bridge-core and bridge-compiler
- Implement matchesRequestedFields utility with dot-separated path and wildcard support
- Runtime: filter output fields in ExecutionTree.run() and resolveNestedField()
- Compiler: filter output wires and use backward reachability for dead code elimination
- Update compiler cache key to include sorted requestedFields
- Add 20 shared parity tests covering field filtering, tool skipping, A||B→C chains, wildcards

Co-authored-by: aarne <82001+aarne@users.noreply.github.com>

* docs: add sparse fieldsets documentation and changeset

Co-authored-by: aarne <82001+aarne@users.noreply.github.com>

* refactor: address code review feedback (validation, perf, docs)

Co-authored-by: aarne <82001+aarne@users.noreply.github.com>

* Lint & build

* Move graphql tests

* refactor: remove check exports script and related commands

* Reorder and update CI steps in test workflow

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aarne <82001+aarne@users.noreply.github.com>
Co-authored-by: Aarne Laur <aarne.laur@gmail.com>

* CLI mode in the Playground

* docs: Review

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: aarne <82001+aarne@users.noreply.github.com>
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.

Unified Sparse Fieldsets & GraphQL Lookahead Architecture

2 participants