a post-component library for building user-interfaces on the web.
at push-kluylotpyvvr 45 lines 1.3 kB view raw
1import type { Renderable } from '../index.ts' 2import { assert, is_renderable } from '../shared.ts' 3import { type Cleanup } from './util.ts' 4 5export interface Controller { 6 _mount_callbacks: (() => Cleanup)[] 7 _unmount_callbacks: Cleanup[] 8 _invalidate: Map<object, () => void> 9} 10 11export const controllers: WeakMap<Renderable, Controller> = new WeakMap() 12 13export function get_controller(renderable: Renderable): Controller { 14 let controller = controllers.get(renderable) 15 if (!controller) 16 controllers.set( 17 renderable, 18 (controller = { 19 _mount_callbacks: [], 20 _unmount_callbacks: [], 21 _invalidate: new Map(), 22 }), 23 ) 24 return controller 25} 26 27export function invalidate(renderable: Renderable): void { 28 const controller = controllers.get(renderable) 29 assert(controller, 'the renderable has not been rendered') 30 controller._invalidate.forEach(invalidate => invalidate()) 31} 32 33export function onMount(renderable: Renderable, callback: () => Cleanup): void { 34 assert(is_renderable(renderable), 'expected a renderable') 35 const controller = get_controller(renderable) 36 if (controller._invalidate.size) { 37 controller._unmount_callbacks.push(callback()) 38 } else { 39 controller._mount_callbacks.push(callback) 40 } 41} 42 43export function onUnmount(renderable: Renderable, callback: () => void): void { 44 onMount(renderable, () => callback) 45}