Skip to content

feat(loom): add template-first API and migrate example app#52

Open
kattsushi wants to merge 13 commits into
devfrom
feat/loom-template-first-api
Open

feat(loom): add template-first API and migrate example app#52
kattsushi wants to merge 13 commits into
devfrom
feat/loom-template-first-api

Conversation

@kattsushi
Copy link
Copy Markdown
Contributor

Closes #51

PR Type

  • Bug fix
  • New feature
  • Documentation only
  • Code refactoring
  • Maintenance/tooling
  • Breaking change

Summary

  • add the imported html template authoring path and typed renderable composition to @effectify/loom
  • migrate apps/loom-example-app to teach the template-first API while preserving SSR/runtime parity
  • keep legacy compatibility seams explicit (View.input() composer seam and template DOM support for SSR/tests)

Changes

File Change
packages/loom/** Added html-first rendering, Renderable<E, R>, View.use, View.match, boundary helpers, tests, and README updates
apps/loom-example-app/src/** Migrated routes/components to the new template-first API and restored green SSR/dev baseline
apps/loom-example-app/tests/** Updated source-shape/runtime tests and added template DOM support coverage
.gitignore Ignore coverage-json/ artifacts

Test Plan

  • pnpm nx run @effectify/loom:test
  • pnpm nx run loom-runtime:test
  • pnpm nx run @effectify/loom:typecheck
  • pnpm nx run @effectify/loom-example-app:test
  • pnpm nx run @effectify/loom-example-app:typecheck
  • Manually verified nx run @effectify/loom-example-app:dev loads successfully after the jsdom bundling fix

Contributor Checklist

  • Linked an approved issue
  • Added exactly one type:* label
  • No shell scripts changed
  • Docs updated where behavior changed
  • Conventional commit format used
  • No Co-Authored-By trailers

@kattsushi kattsushi added the type:feature New feature work label Apr 28, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3685e4db-f034-44b9-9f01-66abcf9bc718

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/loom-template-first-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kattsushi
Copy link
Copy Markdown
Contributor Author

Final Summary

This PR completes the Loom template-first transition in a single coherent branch.

What’s included

  • Introduces the new Loom template-first authoring model:

    • explicit imported html
    • Renderable<E, R>
    • View.use(...)
    • View.match(...)
    • View.catch* / View.provide*
    • explicit View.for(...) list composition
  • Migrates apps/loom-example-app to the new preferred API so the example app teaches the same direction as the package.

  • Adds template-native form directives:

    • web:input
    • web:submit
  • Removes the SSR/import-time DOM shim requirement:

    • no more ensureTemplateDocument()
    • no more withTemplateDocument(...)
    • no template authoring dependence on ambient globalThis.document
  • Completes the follow-up sweep:

    • deprecates legacy View.button / View.input / View.link as compatibility-only helpers
    • adds web:class / web:style
    • adds reactive accessor sugar (${state.foo} reactive, ${state.foo()} snapshot)
    • hardens template/runtime/router/example-app coverage and assertions

Validation

Confirmed green with relevant Nx targets, including:

  • @effectify/loom:test
  • @effectify/loom:typecheck
  • loom-runtime:test
  • @effectify/loom-router:test
  • @effectify/loom-example-app:test
  • @effectify/loom-example-app:typecheck

Notes

  • Legacy helper compatibility is preserved; this PR marks the new path as the documented default.
  • Remaining unrelated local workspace noise was intentionally kept out of the PR.

@kattsushi
Copy link
Copy Markdown
Contributor Author

Final Summary

This PR now completes a much broader Loom DX sweep than the original template-first change.

What’s included

  • Introduces the new Loom template-first authoring model:

    • explicit imported html
    • Renderable<E, R>
    • View.use(...)
    • View.match(...)
    • View.catch* / View.provide*
    • explicit View.for(...) list composition
  • Migrates apps/loom-example-app to the new preferred API so the example app teaches the same direction as the package.

  • Adds template-native form directives:

    • web:input
    • web:submit
  • Removes the SSR/import-time DOM shim requirement:

    • no ensureTemplateDocument()
    • no withTemplateDocument(...)
    • no template authoring dependence on ambient globalThis.document
  • Completes the follow-up sweep:

    • deprecates legacy View.button / View.input / View.link as compatibility-only helpers
    • adds web:class / web:style
    • adds reactive accessor sugar (${state.foo} reactive, ${state.foo()} snapshot)
    • hardens template/runtime/router/example-app coverage and assertions
  • Redesigns the router public story:

    • builder-first router composition
    • improved route-module exports (export default preferred, explicit component still compatible)
    • stronger route context/service inference with less handler annotation noise
  • Simplifies component authoring ergonomics:

    • Component.make() as the lower-ceremony default
    • Component.make("Name") kept for explicit metadata/observability
    • View.of(...) for trivial composition while View.use(...) remains the advanced path
  • Reduces bootstrap/runtime ceremony in the example app:

    • removes document.ts and app-config.ts
    • removes entry-browser.ts, src/jsdom.d.ts, router-runtime.ts, and todo-route-submission.ts
    • keeps the example app focused on router.ts, entry-server.ts, and entry-client.ts as the primary public surface

Validation

Confirmed green with relevant Nx targets, including:

  • @effectify/loom:test
  • @effectify/loom:typecheck
  • loom-runtime:test
  • @effectify/loom-router:test
  • @effectify/loom-router:typecheck
  • @effectify/loom-nitro:test
  • @effectify/loom-nitro:typecheck
  • @effectify/loom-vite:test
  • @effectify/loom-vite:typecheck
  • @effectify/loom-example-app:test
  • @effectify/loom-example-app:typecheck

Notes

  • Legacy helper compatibility is preserved; the PR makes the template-first and lower-ceremony paths the documented default.
  • The example app now reflects the intended consumer story much more directly, with fewer framework-facing support files.
  • Remaining unrelated local workspace noise was intentionally kept out of the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:feature New feature work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant