Skip to content

feat: call composables and compile .uf.ts modules - #74

Merged
alexgrozav merged 2 commits into
milestone-m5-uxf-443from
composable-calls-uxf-461
Oct 29, 2026
Merged

alexgrozav merged 2 commits into
milestone-m5-uxf-443from
composable-calls-uxf-461

Conversation

@alexgrozav

@alexgrozav alexgrozav commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

What changed

A component can now call a composable from a .uf.ts module, and compile() takes a .uf.ts source. No target emits a composable or its call yet: each target's composables lane adds that, so every framework's output is unchanged.

  • The analyser. An import of a .uf.ts module resolves like a child's, through the compiler's resolver. const { on, toggle } = useToggle(false) at the top level of the setup lowers to a Use item. Each argument is read as its parameter's kind says (a value once, a getter as a computed's, a callback as client code), and each member becomes a used* binding of the member's kind. Writing a returned ref is UF2036. A reactive read passed to a value parameter is UF2007, a warning. A template or getter that calls a returned function the API doesn't mark pure is UF2014. A call in any other form is UF1002.
  • The resolver returns a .uf.ts module's API with its composables.
  • The compiler. compile() calls each target's emitComposable, which codegen's Target gains as an optional method. A target without it reports UF1002 for the composable. CompileResult.dependencies lists the .uf.ts modules a source imports, and owners names a composable's files.
  • The unplugin loads a .uf.ts file under each target's composable id (/abs/useToggle.uf.ts, with .svelte.ts added on Svelte and .ts on Angular). It resolves an output's import of a composable's output to that id.
  • The analyser's corpus test reads a case's .uf.ts modules and takes a root. Two fixture cases under packages/analyzer/test/fixtures/cases prove both.

Checklist

  • The title follows Conventional Commits, as in feat(web): sell the next framework on the homepage.
  • pnpm format:check, pnpm lint, pnpm check-types and pnpm test pass. The first three passed. The integration suite and the analyser, compiler, unplugin, codegen, repo, target, testing and umbrella tests passed; the whole pnpm test did not run.
  • Changes to a published package: a changeset from pnpm changeset (see .changeset/README.md).
  • Homepage changes: pnpm build, then pnpm --filter web lighthouse, still scores at least 0.95 in every category.

A component imports a .uf.ts module's composables, resolved like a child,
and calls each at the top level of its setup with const { … } = useX(…),
which lowers to a Use item: each argument as its parameter's kind reads
it, each member a used* binding of the member's kind. A write of a
returned ref is UF2036, and a reactive read passed to a value parameter
UF2007.

compile() takes a .uf.ts source and calls each target's emitComposable,
optional in codegen's Target until each target's composables lane: a
target without it reports UF1002 for the composable. The resolver gives
a .uf.ts module's composables, and CompileResult.dependencies lists them.
The unplugin loads a .uf.ts file under each target's composable id.

The analyser's corpus test reads a case's .uf.ts modules, and a fixture
root proves it.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://composable-calls-uxf-461-unframework.blue-water-0397.workers.dev (commit cdce535)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://dfe81b50-unframework.blue-water-0397.workers.dev cdce535 2026-10-29T08:26:07.196Z Visit the dashboard ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://b889249c-unframework.blue-water-0397.workers.dev 661fb6e 2026-10-28T12:12:35.239Z Visit the dashboard ↗

A local function that calls a returned function the API doesn't mark
pure is impure too (UF2014). A returned ref passed to watch is watched
through a getter of its value, with a safe fix (UF2020). The unplugin
leaves Vite's file queries on an authored .uf.ts to Vite, and fails the
authored file loudly on Svelte and Angular, whose ids have a suffix. The
analyser's README describes the call site.

Co-authored-by: multica-agent <github@multica.ai>
@alexgrozav
alexgrozav merged commit 10b7f1b into milestone-m5-uxf-443 Oct 29, 2026
48 of 49 checks passed
@alexgrozav
alexgrozav deleted the composable-calls-uxf-461 branch October 29, 2026 08:49
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.

1 participant