@tempots/core
v2.0.0
Published
Core types and utilities for multi-context Tempo framework
Maintainers
Readme
@tempots/core
Core types and utilities for multi-context Tempo framework.
Overview
@tempots/core provides the foundational types and utilities that are shared across all Tempo rendering contexts (DOM, ThreeJS, Konva, PixiJS, etc.). This package enables a consistent programming model across different rendering targets while maintaining strong type safety.
Installation
pnpm add @tempots/coreCore Concepts
Renderable
A Renderable is an object that can be rendered into a specific context. It has two properties:
type: A symbol for runtime type checkingrender(ctx): A method that renders content and returns a cleanup function
import { Renderable, RenderContext, Clear } from '@tempots/core'
const MY_TYPE = Symbol('MY_RENDERABLE')
const myRenderable: Renderable<RenderContext, typeof MY_TYPE> = {
type: MY_TYPE,
render: (ctx) => {
// Render logic here
return (removeTree) => {
// Cleanup logic here
}
}
}RenderContext
The base interface for all rendering contexts. Context-specific implementations (DOM, ThreeJS, etc.) extend this interface with their own methods.
interface RenderContext {
clear(removeTree: boolean): void
}HierarchicalContext
Extended interface for contexts that support hierarchical rendering with ordered children. Provides the makeRef() method for creating reference markers that preserve insertion points.
interface HierarchicalContext extends RenderContext {
makeRef(): this
}Clear
A function that cleans up rendered content. The removeTree parameter indicates whether to remove the entire tree or just event listeners and subscriptions.
type Clear = (removeTree: boolean) => voidTNode
A flexible type representing any content that can be rendered:
type TNode<CTX extends RenderContext, TType extends symbol> =
| Renderable<CTX, TType>
| Value<string>
| undefined
| null
| Renderable<CTX, TType>[]Value
Represents a value that can be either static or reactive (a Signal):
type Value<T> = T | Signal<T>API
createRenderable
Creates a renderable object from a render function and type symbol.
import { createRenderable } from '@tempots/core'
const MY_TYPE = Symbol('MY_RENDERABLE')
const myComponent = createRenderable(MY_TYPE, (ctx) => {
// Render logic
return (removeTree) => {
// Cleanup logic
}
})makeProviderMark
Creates a unique symbol for dependency injection.
import { makeProviderMark } from '@tempots/core'
interface UserService {
getUser(id: string): Promise<User>
}
const USER_SERVICE = makeProviderMark<UserService>('UserService')Usage with Context-Specific Packages
This package is typically used indirectly through context-specific packages like @tempots/dom, @tempots/three, etc. Those packages provide higher-level APIs built on these core types.
Example: DOM Context
// In @tempots/dom
import { createRenderable, type Renderable } from '@tempots/core'
import type { DOMContext } from './dom-context'
export const DOM_RENDERABLE_TYPE = Symbol('DOM_RENDERABLE')
export type DOMRenderable = Renderable<DOMContext, typeof DOM_RENDERABLE_TYPE>
export function domRenderable(
renderFn: (ctx: DOMContext) => Clear
): DOMRenderable {
return createRenderable(DOM_RENDERABLE_TYPE, renderFn)
}Example: ThreeJS Context
// In @tempots/three
import { createRenderable, type Renderable } from '@tempots/core'
import type { ThreeContext } from './three-context'
export const THREE_RENDERABLE_TYPE = Symbol('THREE_RENDERABLE')
export type ThreeRenderable = Renderable<ThreeContext, typeof THREE_RENDERABLE_TYPE>
export function threeRenderable(
renderFn: (ctx: ThreeContext) => Clear
): ThreeRenderable {
return createRenderable(THREE_RENDERABLE_TYPE, renderFn)
}Type Safety
The symbol-based branding system ensures compile-time type safety:
// ✅ Valid: DOM renderable in DOM context
html.div(html.span('Hello'))
// ❌ Invalid: ThreeJS renderable in DOM context
html.div(mesh.box({ width: 1, height: 1, depth: 1 }))
// Type error: ThreeRenderable is not assignable to DOMNodeLicense
Apache-2.0
Contributing
See the main Tempo repository for contribution guidelines.
