From 70dd6afd1891ce5b51c05b668809a21ee0132328 Mon Sep 17 00:00:00 2001 From: jack perkins Date: Thu, 4 Dec 2025 16:22:05 +0100 Subject: [PATCH 1/2] Add a drop updates button per instance for testing eventual consistency --- frontend/Instance.tsx | 15 +++++++++++++-- frontend/InstanceHeader.tsx | 9 ++++++++- sim/create.ts | 1 - sim/webxdc.ts | 18 ++++++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/frontend/Instance.tsx b/frontend/Instance.tsx index b464418..7aa3eaf 100644 --- a/frontend/Instance.tsx +++ b/frontend/Instance.tsx @@ -1,4 +1,4 @@ -import { Component, Show } from "solid-js"; +import { Component, Show, createSignal } from "solid-js"; import { Flex, createDisclosure, notificationService } from "@hope-ui/solid"; import { Instance as InstanceData } from "../types/instance"; @@ -12,12 +12,13 @@ const Instance: Component<{ setSearch: (search: Search) => void; }> = (props) => { let iframeRef: HTMLIFrameElement | undefined = undefined; + let [dropUpdates, setDropUpdates] = createSignal(false); const handleReload = () => { if (iframeRef == null) { return; } - + setDropUpdates(false) // reset our state because inner sim/webxdc state is reset in reload iframeRef.contentWindow?.postMessage("reload", props.instance.url); notificationService.show({ @@ -29,6 +30,14 @@ const Instance: Component<{ defaultIsOpen: false, }); + const toggleDropUpdates = () => { + if (iframeRef == null) { + return; + } + setDropUpdates(!dropUpdates()) + iframeRef.contentWindow?.postMessage({ name: "dropUpdates", value: dropUpdates()}, props.instance.url) + } + const getStyle = () => { return { // XXX these dimensions should be configurable somehow @@ -49,6 +58,8 @@ const Instance: Component<{ onStart={onOpen} onStop={onClose} isStarted={isOpen} + dropUpdates={dropUpdates()} + onToggleDropUpdates={toggleDropUpdates} /> void; onStop: () => void; isStarted: Accessor; + dropUpdates: boolean; + onToggleDropUpdates: () => void; }> = (props) => { const sentCount = createMemo(() => { return sent(props.instance.id); @@ -113,6 +115,11 @@ const InstanceHeader: Component<{ onClick={() => handleRemoveInstance(props.instance.id)} icon={} /> + } + /> ); diff --git a/sim/create.ts b/sim/create.ts index d7a6307..6bb4e40 100644 --- a/sim/create.ts +++ b/sim/create.ts @@ -112,7 +112,6 @@ export function createWebXdc( setUpdateListener: (listener, serial = 0): Promise => { transport.onMessage((message) => { if (isUpdatesMessage(message)) { - log("recv update", message.updates); for (const update of message.updates) { listener(update); } diff --git a/sim/webxdc.ts b/sim/webxdc.ts index a8d8b02..a833f52 100644 --- a/sim/webxdc.ts +++ b/sim/webxdc.ts @@ -17,12 +17,27 @@ export class DevServerTransport implements Transport { messageListener: SocketMessageListener | null = null; promise: Promise; resolveInfo!: (info: Info) => void; + dropUpdates: boolean = false; constructor(url: string) { this.socket = new WebSocket(url); this.promise = new Promise((resolve) => { this.resolveInfo = resolve; }); + window.addEventListener("message", (event) => { + const isAllowed = + event.origin.includes("localhost:") || + (location.host.endsWith(".webcontainer.io") && + event.origin.includes(".webcontainer.io")); + if (!isAllowed) { + return; + } + if (typeof event.data === 'object') { + if (event.data.name === 'dropUpdates') { + this.dropUpdates = event.data.value + } + } + }); } send(data: any): void { @@ -34,6 +49,9 @@ export class DevServerTransport implements Transport { this.socket.removeEventListener("message", this.messageListener); } const listener = (event: Event): void => { + if (this.dropUpdates) { + return + } callback(JSON.parse((event as any).data)); }; this.messageListener = listener; From 174fd9eeafd08d42519798601a928957325d778f Mon Sep 17 00:00:00 2001 From: jack perkins Date: Thu, 4 Dec 2025 17:28:18 +0100 Subject: [PATCH 2/2] swap dropUpdates envelop icon for Wifi/offline icons --- frontend/InstanceHeader.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/InstanceHeader.tsx b/frontend/InstanceHeader.tsx index af9f170..adbd8eb 100644 --- a/frontend/InstanceHeader.tsx +++ b/frontend/InstanceHeader.tsx @@ -8,7 +8,8 @@ import { notificationService, } from "@hope-ui/solid"; import { IoRefreshOutline, IoStop, IoPlay } from "solid-icons/io"; -import { FiExternalLink, FiMail, FiTrash } from "solid-icons/fi"; +import { FiExternalLink, FiTrash } from "solid-icons/fi"; +import { RiDeviceWifiLine, RiDeviceWifiOffLine } from 'solid-icons/ri' import type { Instance as InstanceData } from "../types/instance"; import { sent, received, mutateInstances } from "./store"; @@ -118,7 +119,7 @@ const InstanceHeader: Component<{ } + icon={props.dropUpdates ? : } />