WASI support: build SQLiteKit without SwiftNIO or AsyncKit - #4
Draft
scottmarchant wants to merge 3 commits into
Draft
WASI support: build SQLiteKit without SwiftNIO or AsyncKit#4scottmarchant wants to merge 3 commits into
scottmarchant wants to merge 3 commits into
Conversation
Gate the parts of SQLiteKit that require SwiftNIO or AsyncKit with `#if canImport(...)` so the package still builds on platforms where they are unavailable (the next commit elides them on WASI). Keying on `canImport` rather than on a platform keeps these in step with the gates sqlite-nio and sql-kit apply to the same dependencies. When the modules are present the gates are unconditionally true and nothing changes. When they are absent: - `SQLiteConnectionSource` — a `ConnectionPoolSource` over AsyncKit and `NIOThreadPool` — drops out entirely, along with the `AsyncKit` re-export. Callers use sqlite-nio's concrete async `SQLiteConnection` directly; there is no connection pool on those platforms. - The `SQLDatabase` wrapper's `eventLoop`, its `execute(sql:_:) -> EventLoopFuture<Void>` overload, and `withSession(_:)` (which rides sqlite-nio's protocol-level `withConnection`) drop out. SQLKit removes the first two as protocol requirements on the same platforms and supplies a default for the third. - `SQLiteDataDecoder`'s JSON fallback reads a `[UInt8]` blob rather than a `ByteBuffer`, matching `SQLiteData`'s representation there. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Neither SwiftNIO nor AsyncKit builds for wasm32-unknown-wasip1, so SQLiteKit currently cannot be configured for that platform at all. Gate the NIOFoundationCompat and AsyncKit products on `.when(platforms: nonWASIPlatforms)` in both manifests; because target dependency conditions are evaluated per platform, the resolved dependency set is unchanged everywhere else, and on WASI SQLiteKit compiles the pool-free, async-only surface guarded in the previous commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`vapor/ci`'s reusable unit-test workflow already knows how to build a package for `wasm32-unknown-wasip1`; sqlite-kit simply had not opted in. Turn the lane on so the SwiftNIO-free path cannot regress unnoticed. sql-kit already passes `with_wasm: true` to the same workflow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds SQLiteKit on
wasm32-unknown-wasip1without SwiftNIO or AsyncKit. 8 files, +50/−4, no Embedded Swift content. The Embedded work is stacked on top in a separate PR.This should land last of the three — after the sqlite-nio and sql-kit WASI PRs — and then its version floors get bumped so the WASI path resolves without local wiring. Its native build and test suite work against the released sqlite-nio 1.9.0+ / sql-kit 3.29.3+ today, so ordering only matters for the WASI lane.
Why the base branch is
base/vapor-mainbase/vapor-mainis an exact snapshot ofvapor/sqlite-kit@mainat492c46e("Add permissions to API docs workflow", 2026-06-18). It deliberately excludes this fork's one extra commit,8374d3a"feat: Enable WebAssembly compilation (#3)" — that's the NIOAsyncRuntime approach, which depends onPassiveLogic/nio-async-runtimeand gates onos(WASI). This PR supersedes it. That path is dead upstream sinceapple/swift-nio#3487was closed unmerged, and a pre-1.0 dependency isn't acceptable to vapor anyway.Rebasing this branch onto real
vapor/mainis a no-op.What changed
feat: make the SwiftNIO/AsyncKit surface conditional—#if canImport(...)around the parts that need those modules:SQLiteConnectionSourceis whole-file gated oncanImport(AsyncKit), along with theAsyncKitre-export. There is no connection pool on WASI. That's a real functional loss and I want to be upfront about it — callers use sqlite-nio's concrete asyncSQLiteConnectiondirectly. It's tolerable because WASI preview 1 is single-threaded, so a pool buys nothing there.SQLDatabasewrapper'seventLoop, itsEventLoopFutureexecuteoverload, andwithSession(_:)gate oncanImport(NIOCore), matching what SQLKit does to the corresponding protocol requirements.SQLiteDataDecoder's JSON fallback reads a[UInt8]blob, matchingSQLiteData's representation where SwiftNIO is absent.build: elide SwiftNIO and AsyncKit on WASI— 13 lines, applied identically to bothPackage.swift(tools 5.8) andPackage@swift-5.9.swift, so 5.9+ toolchains aren't silently downgraded to the 5.8 base..wasiis available inPackageDescriptionfrom tools 5.6, so the 5.8 manifest is fine.ci: build for WebAssembly in CI—vapor/ci's reusable workflow already has the lane; sqlite-kit had nowith:block at all.On AsyncKit specifically
Upstream
vapor/async-kitdoes not compile for WASI, so this elides it rather than building it. That means the async-kit wasm PR (vapor#111) is not a prerequisite for any of this — a genuine simplification, and useful given that PR is blocked on dependency policy. If async-kit ever gains WASI support the condition can simply be relaxed and the pool comes back.The two things worth arguing about
nonWASIPlatformsis a whitelist, not an exclusion — same as the sibling PRs. SwiftPM has no "all except" form. Upstreamapple/swift-niouses the identical idiom (let historicalNIOPosixDependencyRequired: [Platform], from "Add support for WASILibc (#2671)"), as doesapple/swift-crypto. Doc comment pinned to the tools-version sits above the list. An unconditional change isn't possible; neither dependency builds for WASI.canImport(...)is build-wide, not target-scoped. Correct here because all three packages gate the same modules on the same condition. All these gates are inSources/, never in the manifest.Verification
swift build+swift test(against released siblings)--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendableSendablewarnings it emits are pre-existing onbase/vapor-mainswift package diagnose-api-breaking-changes base/vapor-main--swift-sdk swift-6.3.1-RELEASE_wasm, same CI flagsswift package edit --path(the committed manifests keep upstreamvapor/...URLs)NIOCore,NIOPosix,NIOEmbedded,NIOFoundationCompat,NIOConcurrencyHelpers,NIO,AsyncKitall produce 0 object files;nmover the SQLiteKit/SQLiteNIO/SQLKit wasm objects finds 0 NIO/EventLoop/ByteBuffer/AsyncKit symbolsThe
unit-tests / wasmcheck won't run while this is a draft (vapor/ciguards it withif: !draft). It will also fail until the sibling PRs land and the version floors are bumped, since the released sqlite-nio/sql-kit have no WASI support — that's the sequencing note at the top.Constraints held
No SwiftPM traits, no versioned manifest added (the existing
Package@swift-5.9.swiftis preserved and gets the same hunk), no tools-version bump, no new dependency, no fork URLs. Manifest count unchanged at 2.