Guide
Architecture Overview
This chapter introduces the layered architecture and runtime data flow of TSone, giving you a global picture before you dive into each subsystem.
Design Goals
- Lightweight: the core package has zero runtime dependencies and relies only on standard browser DOM interfaces.
- Object-oriented: the framework and application code are organized around class components with explicit object relationships.
- Strategy-based rendering: render behavior is dispatched to dedicated strategies by VNode type, so new capabilities are added by extending strategies.
- Bun-native: development, testing, building, and documentation are all driven by Bun.
Layered Architecture
The TSone runtime is organized from top to bottom into an app layer, a component layer, a render layer, and runtime infrastructure, accompanied by a dedicated Bun-native toolchain:
App Layer
The createApp() function creates a OneApp instance, the single entry point of an application. It is responsible for:
- Mounting the root component and injecting
AppContext(config, version, router) into it. - Installing plugins through
use(plugin)and calling their hooks during the app lifecycle. - Providing global
provide/inject, global state, and configuration. - Generating an HTML document shell through
renderHtmlDocument()for the CLI dev/build pipeline.
Component Layer
All UI is expressed with class components that extend Component<Props, State>. Each component owns reactive state, a local styleManager, and a templateEngine, declares its structure in render(): VNode, and hooks into the full lifecycle, events (emit/on), dependency injection, and error boundaries.
Render Layer
The RendererContext dispatches VNodes to five render strategies (text, element, component, slot, and transition group) using the strategy pattern, and exposes a unified mount / patch / unmount interface. On component updates it diffs the old and new VNodes and converges changes into minimal DOM operations.
Runtime Infrastructure
ReactiveSystem: Proxy-based dependency tracking and dispatch, paired withReactiveSchedulerto merge a batch of state changes into a single re-render.Router: route matching, history/hash modes, redirects, and navigation guards; RouterView renders the matched component.StyleManager: one instance per component, compiling style rules into CSS text and injecting a<style>element.
Toolchain
@geektech/tsone-cli provides tsone dev, tsone build, and the development proxy, configured through tsone.config.ts. It reuses renderHtmlDocument() to produce entry pages and performs the first render of the component tree inside a DOM-like document.
Runtime Data Flow
Mount Flow
- createApp builds a OneApp; mount() resolves the mount point and constructs the root component instance.
- The root component initializes reactive state, styles, and the template engine, then calls render() to produce a VNode after beforeMount.
- RendererContext mounts the VNode into the real DOM through its strategies, then onMounted fires.
- Plugins and global state are injected at the app layer; components access global capabilities through getContext() and the router getter.
Update Flow
Component state is a reactive object; properties read during render become dependencies of the component updateEffect. When state changes, ReactiveScheduler enqueues updateEffect into the microtask queue for batched execution: render() runs again to produce a new VNode, and RendererContext applies DOM diffs. Use flushSync() to read the DOM synchronously, or await nextTick() in async code.
Unmount Flow
unmount walks the VNode tree recursively: beforeUnmount fires first, then child components are unmounted, events and slots are cleared, the styleManager and template bindings are destroyed, the updateEffect is stopped, and onUnmounted fires last.
Design Patterns and Object Relationships
The framework is organized around SOLID principles, with explicit relationships between classes and modules:
| Pattern | Location | Description |
|---|---|---|
| Strategy | RendererContext → RenderStrategy | Render behavior is dispatched by VNode type; new rendering capabilities only need a new strategy |
| Singleton | ReactiveSystem.getInstance() | A single global dependency-tracking and dispatch center |
| Observer | effect / updateEffect + ReactiveScheduler | State changes automatically schedule component re-renders |
| Composition | Component holds StyleManager and TemplateEngine | Style and template capabilities are composed into components on demand |
| Dependency injection | app.provide / component.provide + inject | Capabilities resolve up the component parent chain, decoupling consumers from providers |
| Implementation | RenderStrategy interface + five strategy classes | Render strategies depend on an abstraction rather than concrete implementations |
Public Surface and Package Structure
The TSone public surface stays small and clear:
- @geektech/tsone: core APIs (createApp, Component, the reactive family, VNode, renderHtmlDocument, StyleSheet, Transition, TransitionGroup, KeepAlive).
- @geektech/tsone/router: createRouter, Router, RouterView, RouterLink, useRouter.
- @geektech/tsone-cli: defineConfig, tsone dev, tsone build, and the development proxy.
Summary
TSone organizes its runtime with the vertical layering of app → component → render, supported horizontally by the reactive system, router, and style management. Continue with Core Concepts, Component System, Reactive System, Routing, and Style Management for the concrete implementations.