Untrusted imports that return Promise<T> are currently auto-awaited — the compiler silently generates await (async () => { try { ... await call() ... } catch ... })(). The caller gets Result<T, Error> without writing |> await.
This hides async behavior, contradicting Floe's design principle that effects are explicit in types (|> await requires Promise<T> return type).
Proposed change
Remove the outer await from the untrusted IIFE. The IIFE still catches rejections, but returns Promise<Result<T, Error>> instead of Result<T, Error>. The user explicitly awaits:
// Before (hidden async):
const result = npmAsyncFn() // Result<T, Error> — silently async
// After (explicit):
const result = npmAsyncFn() |> await // Promise<Result<T, Error>> → Result<T, Error>
Also update
docs/site/src/content/docs/docs/reference/stdlib/promise.md — remove auto-await claims
docs/site/src/pages/index.astro — fix getUser example
docs/llms.txt — update npm import section
docs/design.md — update async section
- Example apps if affected
Untrusted imports that return
Promise<T>are currently auto-awaited — the compiler silently generatesawait (async () => { try { ... await call() ... } catch ... })(). The caller getsResult<T, Error>without writing|> await.This hides async behavior, contradicting Floe's design principle that effects are explicit in types (
|> awaitrequiresPromise<T>return type).Proposed change
Remove the outer
awaitfrom the untrusted IIFE. The IIFE still catches rejections, but returnsPromise<Result<T, Error>>instead ofResult<T, Error>. The user explicitly awaits:Also update
docs/site/src/content/docs/docs/reference/stdlib/promise.md— remove auto-await claimsdocs/site/src/pages/index.astro— fix getUser exampledocs/llms.txt— update npm import sectiondocs/design.md— update async section