a post-component library for building user-interfaces on the web.
at main 44 lines 948 B view raw
1import type { Renderable } from 'dhtml' 2import { invalidate, onMount } from 'dhtml/client' 3import type { Bus } from './bus' 4import { suspend } from './suspense' 5 6export interface Query<T> { 7 (): T 8 revalidate(): void 9} 10 11type QueryFn<T> = (prev: T | null) => Promise<T> 12 13export function createQuery<T>(renderable: Renderable, fn: QueryFn<T>): Query<T> { 14 let value: T | null = null 15 let promise = handle() 16 17 async function handle() { 18 value = await fn(value) 19 invalidate(renderable) 20 return value 21 } 22 23 function query() { 24 if (value == null) return suspend(renderable, promise) 25 return value 26 } 27 28 query.revalidate = () => { 29 promise = handle() 30 } 31 32 return query 33} 34 35export function createSubscribedQuery<T, Event extends string>( 36 renderable: Renderable, 37 bus: Bus<Event>, 38 event: Event, 39 fn: QueryFn<T>, 40): Query<T> { 41 const query = createQuery(renderable, fn) 42 onMount(renderable, () => bus.subscribe(event, query.revalidate)) 43 return query 44}