a post-component library for building user-interfaces on the web.
at main 74 lines 2.0 kB view raw
1export * as lexer from './shared/lexer.ts' 2 3/** @internal */ 4declare global { 5 var __DEV__: boolean 6} 7 8export interface ToString { 9 toString(): string 10} 11 12export type Displayable = null | undefined | ToString | Node | Renderable | Iterable<Displayable> | HTML | Keyed 13export interface Renderable { 14 render(): Displayable 15} 16 17export function is_renderable(value: unknown): value is Renderable { 18 return (typeof value === 'object' || typeof value === 'function') && value !== null && 'render' in value 19} 20 21export function is_iterable(value: unknown): value is Iterable<unknown> { 22 return (typeof value === 'object' || typeof value === 'function') && value !== null && Symbol.iterator in value 23} 24 25export function assert(value: unknown, message?: string): asserts value { 26 if (!__DEV__) return 27 if (!value) { 28 const error = new Error(message ?? 'assertion failed') 29 Error.captureStackTrace?.(error, assert) // remove assert from the stack trace 30 throw error 31 } 32} 33 34export interface HTML { 35 [html_tag]: true 36 /* @internal */ _statics: TemplateStringsArray 37 /* @internal */ _dynamics: unknown[] 38} 39 40const html_tag: unique symbol = Symbol() 41export function html(statics: TemplateStringsArray, ...dynamics: unknown[]): HTML { 42 return { 43 [html_tag]: true, 44 _dynamics: dynamics, 45 _statics: statics, 46 } 47} 48 49export function is_html(value: unknown): value is HTML { 50 return typeof value === 'object' && value !== null && html_tag in value 51} 52 53export function single_part_template(part: Displayable): HTML { 54 return html`${part}` 55} 56 57export type Key = string | number | bigint | boolean | symbol | object | null 58export interface Keyed extends Renderable { 59 [keyed_tag]: true 60 /** @internal */ _key: Key 61} 62 63const keyed_tag: unique symbol = Symbol() 64export function keyed(displayable: Displayable, key: Key): Keyed { 65 return { 66 [keyed_tag]: true, 67 _key: key, 68 render: () => displayable, 69 } 70} 71 72export function is_keyed(value: any): value is Keyed { 73 return typeof value === 'object' && value !== null && keyed_tag in value 74}