Skip to content

Make controller lifecycle methods async#145

Merged
junyan72 merged 2 commits into
mainfrom
controller-async-investigation
Jul 15, 2026
Merged

Make controller lifecycle methods async#145
junyan72 merged 2 commits into
mainfrom
controller-async-investigation

Conversation

@junyan72

Copy link
Copy Markdown
Contributor

Summary

Mark the lifecycle methods on StreamedMarkdownController and MarkdownController as async so their call sites — all of which run inside .task { } — can await them directly instead of relying on implicit fire-and-forget. This keeps the concurrency boundary explicit at the view layer and aligns both controllers with the package's Swift-concurrency conventions.

  • StreamedMarkdownController.start() / end() are now async
  • MarkdownController.onAppear(markdown:) / onDisappear() are now async
  • .task call sites now await; the sync .onDisappear callbacks wrap the call in a Task

The fire-and-forget interaction hooks (onTableCopyTap, onTableDownloadTap, onContextMenuAppear, onContextMenuTap, onImageTap) and the sync onChange(markdown:) (which only yields into a continuation) intentionally remain synchronous — their call sites are non-async UIKit/AppKit delegate methods and SwiftUI action closures, so making them async would only push a Task { } wrapper out to every call site.

Refs #144

Validation

  • make lint — 0 violations
  • make test — all tests pass
  • make build-sample — BUILD SUCCEEDED

OSS readiness

  • No secrets, internal URLs, private identifiers, or product-only service names were added.
  • Public docs, fixtures, or notices were updated if behavior or dependencies changed. (no public API/doc changes; methods are internal)
  • Third-party dependency changes (adds, removes, version bumps) are intentional and reviewed. (no dependency changes)
  • Streaming/incomplete markdown behavior remains covered by fixtures or tests.

Mark the lifecycle methods on both controllers as async so their call
sites (all inside `.task { }`) can await them directly instead of relying
on implicit fire-and-forget, keeping the concurrency boundary explicit.

- StreamedMarkdownController: `start()` / `end()` are now async
- MarkdownController: `onAppear(markdown:)` / `onDisappear()` are now async
- Update `.task` call sites to `await`; wrap the sync `.onDisappear`
  callbacks in a `Task`

The fire-and-forget interaction hooks and the sync `onChange(markdown:)`
remain synchronous, since their call sites are non-async UIKit/AppKit
delegates and SwiftUI action closures.

Refs #144

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 17e2748f-66c1-4deb-b557-df65a17c84f5

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates controller lifecycle APIs to be async so SwiftUI view-layer .task {} call sites can await them directly, making the concurrency boundary explicit and consistent across DocumentView and StreamedMarkdownView.

Changes:

  • Made MarkdownController.onAppear(markdown:) / onDisappear() async and updated DocumentView to await/wrap calls appropriately.
  • Made StreamedMarkdownController.start() / end() async and updated StreamedMarkdownView call sites accordingly.
  • Introduced a debug print in MarkdownController.onChange(markdown:) (should be removed before merge).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
Sources/MarkdownText/Utilities/MarkdownListener.swift Converts MarkdownController lifecycle methods to async; currently includes an unintended debug log in onChange.
Sources/MarkdownText/UI/DocumentView.swift Awaits controller lifecycle methods from .task and wraps async cleanup in .onDisappear.
Sources/MarkdownText/StreamedMarkdownView.swift Awaits streamed controller lifecycle methods and wraps async cleanup in .onDisappear.

Comment thread Sources/MarkdownText/Utilities/MarkdownListener.swift
A leftover `print("JUN: ...")` debug statement was accidentally included
in `MarkdownController.onChange(markdown:)`. Remove it so the library
does not spam stdout or leak content details in production.

Refs #144

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 17e2748f-66c1-4deb-b557-df65a17c84f5
@junyan72
junyan72 merged commit a5fca03 into main Jul 15, 2026
6 checks passed
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.

2 participants