Skip to content

Comments

[Repo Assist] Migrate AsyncSeq<'T> to BCL IAsyncEnumerable<'T> (v4.0)#231

Merged
dsyme merged 8 commits intomainfrom
repo-assist/v4-bcl-iasyncenumerable-migration-3b81040f29c8a5a6
Feb 22, 2026
Merged

[Repo Assist] Migrate AsyncSeq<'T> to BCL IAsyncEnumerable<'T> (v4.0)#231
dsyme merged 8 commits intomainfrom
repo-assist/v4-bcl-iasyncenumerable-migration-3b81040f29c8a5a6

Conversation

@github-actions
Copy link
Contributor

🤖 Repo Assist here — I'm an automated AI assistant for this repository.

Implements the direction given in #230 by @dsyme: migrate AsyncSeq<'T> to use the standard .NET System.Collections.Generic.IAsyncEnumerable<'T> as the underlying type, with a v4 major version bump.

Fixes #230.


What changed

Before After
type AsyncSeq<'T> = IAsyncEnumerable<'T> (custom library interface) type AsyncSeq<'T> = System.Collections.Generic.IAsyncEnumerable<'T> (BCL)
IAsyncEnumerator<'T> (custom, MoveNext(): Async<'T option>) Internal only: IAsyncSeqEnumerator<'T> (not exported)
ofAsyncEnum / toAsyncEnum performed BCL↔custom conversion ofAsyncEnum / toAsyncEnum are now identity functions
s.GetEnumerator() returning IAsyncEnumerator<'T> s.GetAsyncEnumerator(ct) returning BCL IAsyncEnumerator<'T>

How the internal machinery is preserved

The library's internal pull-based generator infrastructure (Async<'T option>) is unchanged. A new AsyncSeqImpl<'T> class wraps the internal enumerator factory as a BCL IAsyncEnumerable<'T>. An internal GetEnumerator() extension (not exported via .fsi) on IAsyncEnumerable<'T> bridges the two worlds for internal use.

Breaking changes for downstream users

  • Code that implements IAsyncEnumerator<'T> / IAsyncEnumerable<'T> from this library needs updating
  • Code that calls .GetEnumerator() / .MoveNext() directly must switch to .GetAsyncEnumerator(ct) / .MoveNextAsync()
  • ofAsyncEnum and toAsyncEnum are now no-ops (kept for source compatibility but can be removed in v4 final)

What's still TODO before final v4.0.0

  • Fable support: currently untested; the pull-based internal machinery should still work via the adapter, but #if FABLE_COMPILER paths need verification
  • Remove ofAsyncEnum/toAsyncEnum stubs or mark [(Obsolete)]
  • Consider whether IAsyncSeqEnumerator<'T> / AsyncSeqImpl<'T> should be hidden more aggressively (currently un-exported via .fsi but not marked [(EditorBrowsable(Never))])
  • Update RELEASE_NOTES.md and README.md

Test Status

Build succeeded — both netstandard2.0 and netstandard2.1 targets
All 190 tests pass — one test updated from old pull-based API to BCL GetAsyncEnumerator/MoveNextAsync pattern

Generated by Repo Assist

Generated by Repo Assist

To install this workflow, run gh aw add githubnext/agentics/workflows/repo-assist.md@077cdbca7864e820e3425e9598cf1269d3dce05a. View source at https://github.com/githubnext/agentics/tree/077cdbca7864e820e3425e9598cf1269d3dce05a/workflows/repo-assist.md.

…le<'T> (v4.0)

BREAKING CHANGE: AsyncSeq<'T> is now an alias for
System.Collections.Generic.IAsyncEnumerable<'T>, replacing the library's
own IAsyncEnumerator<'T> / IAsyncEnumerable<'T> pull-based interfaces.

Key changes:
- Remove public IAsyncEnumerator<'T> and IAsyncEnumerable<'T> interfaces.
  Code with custom enumerator implementations must be updated.
- AsyncSeq<'T> = System.Collections.Generic.IAsyncEnumerable<'T>
- Internal machinery: IAsyncSeqEnumerator<'T> (pull-based) retained as an
  implementation detail wrapped by AsyncSeqImpl<'T> adapter; not exported.
- AsyncSeqEnumeratorExtensions module: adds GetEnumerator() extension on
  IAsyncEnumerable<'T> for internal use (hidden by .fsi).
- ofAsyncEnum / toAsyncEnum: now identity functions (no-ops).
- Bump version to 4.0.0-alpha.1.
- Update test that used old GetEnumerator()/MoveNext() API to BCL style.

All 190 tests pass.

Fixes #230.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI commented Feb 22, 2026

@dsyme I've opened a new pull request, #232, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 3 commits February 22, 2026 10:48
…MPILER

- In AsyncSeq.fs: wrap AsyncSeq<'T> type alias, AsyncSeqImpl<'T>, and
  AsyncSeqEnumeratorExtensions with #if FABLE_COMPILER / #else / #endif.
  For Fable: AsyncSeq<'T> is a library-specific interface with
  GetEnumerator() returning IAsyncSeqEnumerator<'T>, avoiding ValueTask.
  For non-Fable: keeps existing BCL IAsyncEnumerable<'T> alias and
  ValueTask-based adapter.
- In AsyncSeq.fs: guard UnfoldAsyncEnumerator's IAsyncEnumerable<'T>
  implementation of the library AsyncSeq<'T> interface instead.
- In AsyncSeq.fsi: add #if FABLE_COMPILER guard to expose
  IAsyncSeqEnumerator<'T> and define AsyncSeq<'T> as interface for
  Fable builds; keep BCL type alias for non-Fable.

Verified: dotnet build succeeds, 190/190 tests pass, dotnet fable
compiles without errors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
[WIP] Fix AsyncSeq migration issues and Fable feedback
Copy link
Contributor

Copilot AI commented Feb 22, 2026

@dsyme I've opened a new pull request, #233, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 3 commits February 22, 2026 11:50
Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
Fix Fable compatibility: guard `getIterator` obsolete attribute and complete #if FABLE_COMPILER cleanup
@dsyme dsyme merged commit 24c47ce into main Feb 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants