Experiment to rebuild Diffuse using web applets.
0

Configure Feed

Select the types of activity you want to include in your feed.

1import type { Applet, AppletEvent } from "@web-applets/sdk"; 2 3import { applets } from "@web-applets/sdk"; 4import { effect, signal } from "spellcaster/spellcaster.js"; 5import { xxh32 } from "xxh32"; 6 7//////////////////////////////////////////// 8// 🪟 Applet initialiser 9//////////////////////////////////////////// 10export async function applet<D>( 11 src: string, 12 opts: { 13 addSlashSuffix?: boolean; 14 context?: Window; 15 id?: string; 16 setHeight?: boolean; 17 } = {}, 18): Promise<Applet<D>> { 19 src = `${src}${ 20 src.endsWith("/") 21 ? "" 22 : opts.addSlashSuffix === undefined || opts.addSlashSuffix === true 23 ? "/" 24 : "" 25 }`; 26 27 const existingFrame: HTMLIFrameElement | null = (opts.context || window).document.querySelector( 28 `[src="${src}"]`, 29 ); 30 31 let frame; 32 33 if (existingFrame) { 34 frame = existingFrame; 35 } else { 36 frame = document.createElement("iframe"); 37 frame.src = src; 38 if (opts.id) frame.id = opts.id; 39 40 document.body.appendChild(frame); 41 } 42 43 if (frame.contentWindow === null) { 44 throw new Error("iframe does not have a contentWindow"); 45 } 46 47 const applet = await applets.connect<D>(frame.contentWindow); 48 49 if (opts.setHeight) { 50 applet.onresize = () => { 51 frame.height = `${applet.height}px`; 52 frame.classList.add("has-loaded"); 53 }; 54 } else { 55 if (frame.contentDocument?.readyState === "complete") { 56 frame.classList.add("has-loaded"); 57 } 58 59 frame.addEventListener("load", () => { 60 frame.classList.add("has-loaded"); 61 }); 62 } 63 64 return applet; 65} 66 67//////////////////////////////////////////// 68// 🔮 Reactive state management 69//////////////////////////////////////////// 70export function reactive<D, T>( 71 applet: Applet<D>, 72 dataFn: (data: D) => T, 73 effectFn: (t: T) => void, 74) { 75 const [getter, setter] = signal(dataFn(applet.data)); 76 77 effect(() => effectFn(getter())); 78 79 applet.addEventListener("data", (event: AppletEvent) => { 80 setter(dataFn(event.data)); 81 }); 82} 83 84//////////////////////////////////////////// 85// 🛠️ 86//////////////////////////////////////////// 87export function comparable(value: unknown) { 88 return xxh32(JSON.stringify(value)); 89} 90 91export function isPrimitive(test: unknown) { 92 return test !== Object(test); 93}