a post-component library for building user-interfaces on the web.
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}