Skip to content

feat(o4b): @positron/lit — the Lit DOM renderer (Renderer<S, TemplateResult> + LitHost)#10

Merged
joelteply merged 2 commits into
mainfrom
feat/o4b-2-positron-lit
Jul 3, 2026
Merged

feat(o4b): @positron/lit — the Lit DOM renderer (Renderer<S, TemplateResult> + LitHost)#10
joelteply merged 2 commits into
mainfrom
feat/o4b-2-positron-lit

Conversation

@joelteply

Copy link
Copy Markdown
Contributor

O4b-2 — @positron/lit, the DOM/TS outlier

Second and final slice of O4b. O4b-1 (#9) crossed the contract into TypeScript (the four Rust traits as hand-authored TS interfaces + the web CI gate). This lands the actual DOM renderer on that foundation — the sibling of positron-wgpu on the web surface.

The package

  • renderer.tsLitRenderer<S> = Renderer<S, TemplateResult>. A type alias, not a new interface: the render contract lives once in @positron/core; this file only pins Output = TemplateResult (compression rule — no second source of truth).
  • host.tsLitHost implements core's Host: state flows down (onState → render → injected commit sink), events flow up (onEventinjected event→command mapper). It imports only the TemplateResult type, never a DOM value — DOM-free by construction, so it's headlessly testable.
  • dom.tsdomCommit(container), the one DOM-touching call (Lit's render into a container). The analogue of the wgpu outlier's gpu.rs: quarantined from the pure projection, kept off the headless test path. Same pure/impure split as both Rust outliers.

Proof (headless, no jsdom)

lit.test.ts reuses core's Counter fixture and asserts the projection on the TemplateResult's strings/values — the DOM analogue of wgpu's quad assertions — plus LitHost state-down/event-up (including the undefined/None no-command path). 4/4 pass, typecheck clean across both packages.

Toolchain / drift

Adds npm/lit/ to the workspaces; deps lit ^3.2.0 + @positron/core. The core dep is type-only — lit imports only interfaces from core, all erased under verbatimModuleSyntax, so there's no runtime coupling to core's TS. The existing web CI job (npm installtsc --noEmitnode --test) gates it; no new CI needed.

Decision recorded

The roadmap deferred "does the positron DOM stack subsume or complement continuum's sdk/typescript?" to O4b. Answer: complement. positron owns the portable contract (ViewState/Renderer/Host/Observer + transport-neutral session frames); continuum's SDK owns its Commands/Events/domain types. They meet at ContinuumHost (O5); neither subsumes the other, so there's no merge and no duplicated truth. Written into ARCHITECTURE.md (§ decisions + roadmap, O4b marked landed) and README.

Task #117 (positron O1..O6 build-out). Next: O5 ContinuumHost (in continuum).

🤖 Generated with Claude Code

joelteply and others added 2 commits July 2, 2026 23:02
…Result> + LitHost)

O4b-2 — the DOM/TS outlier of the positron Renderer/Host contract, the
sibling of the wgpu backend on the web surface. Completes O4b (the
contract's TypeScript crossing, foundation landed in O4b-1 / PR #9).

New package `@positron/lit`:
- `renderer.ts` — `LitRenderer<S> = Renderer<S, TemplateResult>`. Not a
  fresh interface: the render contract lives once in @positron/core;
  this only pins the DOM output type (compression rule).
- `host.ts` — `LitHost` implements core's `Host`: state flows down
  (render → injected commit sink), events flow up (injected
  event→command mapper). DOM-free by construction — imports only the
  `TemplateResult` type, never a DOM value — so it's headlessly testable.
- `dom.ts` — `domCommit(container)`, the ONE DOM-touching seam (Lit's
  `render` into a container). The analogue of the wgpu outlier's
  `gpu.rs`: quarantined from the pure projection, off the headless test
  path. Same pure/impure split as both Rust outliers.
- `lit.test.ts` — Counter + CounterLitRenderer fixture (mirrors core's
  contract.test.ts). Asserts the projection headlessly on the
  TemplateResult's `strings`/`values` — the DOM analogue of wgpu's quad
  assertions — plus LitHost state-down/event-up. 4/4 pass, no jsdom.

Toolchain: adds `npm/lit/` to the workspaces; deps `lit ^3.2.0` +
`@positron/core` (type-only — lit imports only interfaces from core, all
erased, so no runtime coupling). The existing `web` CI job gates it.

Docs: ARCHITECTURE.md marks O4b landed and records the deferred
subsume-vs-complement decision — positron's portable contract
(ViewState/Renderer/Host/Observer + session frames) and continuum's
`sdk/typescript` (its Commands/Events/domain types) COMPLEMENT; they meet
at ContinuumHost (O5), neither subsumes the other. README Status +
diagram updated.

Task #117 (positron O1..O6 build-out).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoTjvf5j3Ez13g6k8mRkFo
Review non-blocking nit: in Lit 4, `TemplateResult` becomes possibly-
compiled and drops `.strings`, so the static-structure assertion is the
exact line that will need an `UncompiledTemplateResult` narrowing on that
bump. Note it in place so future-you doesn't have to re-derive it. Comment
only — no behavior change (8/8 still green, typecheck clean).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoTjvf5j3Ez13g6k8mRkFo
@joelteply joelteply merged commit 613e594 into main Jul 3, 2026
3 checks passed
@joelteply joelteply deleted the feat/o4b-2-positron-lit branch July 3, 2026 04:07
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