Skip to content

Migrate LINQ runtime to pipe-based composition for tree-shaking #20

@danfma

Description

@danfma

Background: ADR-0012 documents the current LINQ runtime as an eager wrapper class hierarchy (`EnumerableBase` with one concrete subclass per operator), explicitly noting this is not tree-shakeable and that migration to pipe-based is tracked separately. This is that issue.

Goal

Replace the wrapper-class hierarchy with standalone operator functions composed via `pipe()`, so bundlers can drop operators the user's code never touches. Preserves lazy semantics, preserves the C# LINQ surface on the user side, and only churns the generated TS output (a one-time regeneration event).

Scope

  • Define `OperatorFn<T, R>` type + typed `pipe()` overloads (RxJS-style)
  • Convert every composition operator into a standalone function:
    `where(pred)`, `select(fn)`, `selectMany(fn)`, `orderBy(fn)`, `orderByDescending(fn)`, `take(n)`, `skip(n)`, `distinct()`, `distinctBy(fn)`, `groupBy(fn)`, `concat(other)`, `takeWhile(pred)`, `skipWhile(pred)`, `reverse()`, `zip(other, fn)`, `append(item)`, `prepend(item)`, `union(other)`, `intersect(other)`, `except(other)`
  • Convert every terminal: `toArray`, `toMap`, `toSet`, `first`, `firstOrDefault`, `last`, `lastOrDefault`, `single`, `singleOrDefault`, `any`, `all`, `count`, `sum`, `average`, `min`, `max`, `minBy`, `maxBy`, `contains`, `aggregate`
  • `EnumerableBase.pipe(...operators)` applies a chain to a source
  • Update the declarative LINQ mappings in `src/Metano/Runtime/Linq.cs` to emit `pipe()` chains instead of fluent method calls
  • Keep the fluent API available as optional manual sugar — don't break consumers that wrote code against the current runtime by hand
  • Regenerate all three samples, verify test suites pass, verify bundle size drops when bundling a sample that only uses a few operators
  • Update ADR-0012 status to Superseded once this lands

Constraints

User C# code is unaffected — this is a runtime + lowering refactor. The round-trip is: regenerate, rebuild, re-run tests, ship.

Part of #14.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions