DSD, open/closed template, and light-DOM components that talk through
<main-context>: children register on… callbacks and share updates as events.
Served by Vite via npm run examples; examples/ is linted, formatted and
typechecked.
events maps a name to true, listener options, listen<E>(options?) for an
explicit event type, or custom<T>(options?) for a CustomEvent<T> (the same as
listen<CustomEvent<T>>()). Otherwise an event is typed from HTMLElementEventMap
by name. The array form is gone. handleEvent gets HandledEvent<S>, each event
tagged with its literal type so event.type narrows.
Props live on instances, so statics on the generated class or the base
can't collide with them. Only instance members of the base and the
mixin are reserved now.
WebComponent(spec) builds a custom-element base class from a spec:
shadow root or declarative shadow DOM, template, shared stylesheet
(adopted, or a <style> once per root for light DOM), reflected props
with two-way attribute sync, a per-connection AbortSignal, host event
wiring, and typed element refs.
Types derive exact observedAttributes, prop value types, ref element
types from selectors, and reject prop names that collide with the base
class or mixin members.
Tooling: strict tsconfig, type-aware oxlint, oxfmt, and Vitest browser
mode (Chromium) with type tests.