web: add standalone web worker example - #962
Open
Fristender wants to merge 2 commits into
Open
Conversation
Fristender
marked this pull request as draft
August 16, 2026 22:49
Fristender
marked this pull request as ready for review
August 17, 2026 06:06
Collaborator
|
@Fristender is this PR worth renaming to like |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This requires #961 to be merged first.
Adds a third web target,
web-standalone, that runs the whole dvui app inside a Web Worker: WASM + WebGL on anOffscreenCanvas, events delivered viaSharedArrayBuffer+Atomics, frames returned to the main thread as transferredImageBitmaps. Includes JSPI support so the blocking event loop doesn't starve the worker event loop.Review guide
web-common.js:96-128— shared-memory protocol constants (signal flag, cursors, canvas info, 256-slot event ring, 4 KiB string area). Contract between the two new files; check offsets add up (TOTAL_SHARED_SIZE= 9472).web-standalone.js:33-77—dvuiStandalone()entry: canvas lookup,dvui_debugflag, SharedArrayBuffer/Atomics/COOP-COEP preflight checks.web-standalone.js:105-148—pushEvent/pushString: ring-full drop policy, 32-bit wrap tricks, string-area wraparound (best-effort, no synchronization with worker reads — worth a look).web-standalone.js:158-261— DOM listeners mirroringweb.js(mouse/wheel/key/IME/touch), each pushing ring events.web-standalone.js:264-318— messages from worker:bitmap,cursor,text_input,open_url,download,clipboard_set,panic.web-worker.js:43-119— JSPI detection, suspendingwasmWaitEventJspi/wasmSleepJspi,MessageChannelmacrotask yield, EdgeSTATUS_ACCESS_VIOLATIONrationale comment.web-worker.js:153-186—drainEvents(): key/text events read strings from the shared string area and re-enter wasm viaadd_event.web-worker.js:201-260— init:OffscreenCanvascreation, wasm instantiate,main()viaWebAssembly.promisingwhen JSPI is available.web.zig:42-45andweb.zig:804-836— newwasm_wait_eventextern,InitOptions/initWindow(),waitEventTimeout(), andrenderPresent()now shipping the bitmap.web-standalone.zig:30-46— SDL-standalone-shapedmain(): init → frame →waitEventTimeoutloop.build.zig:998-1006,build.zig:1036-1058,build.zig:1657-1704— separate export-symbol list, separate backend module, andaddWebStandaloneExample().Known gaps vs. web-app (no feature parity yet)
web-common.js:1073-1081); web-app has the real<input type="file">+filesCacheimplementation (web.js:213-265).dvui.dialogsfile open is a silent no-op in standalone.navigator.clipboard.writeText(web-standalone.js:299-303); web-app falls back to hidden-inputexecCommand("copy")for non-secure contexts (web.js:267-283).prefers-reduced-motion— hardcoded to "no preference" (web-worker.js:330-332); web-app queriesmatchMedia(web.js:199-211). Not yet forwarded through the shared buffer.wasm_refresh— no-op in worker mode (web-worker.js:266-268); web-app uses it to schedulerequestAnimationFramerenders (web.js:329-332). Async operations that expect to trigger a repaint won't.initWindow()discards size/min/max/vsync/title/icon (web.zig:822-825); size comes from CSS, title/icon from the HTML.platformstring — sent in the init message (web-standalone.js:325) but never consumed inweb-worker.js.main_loopruns forever (web-standalone.zig:38-45); nothing maps to "window closed".alert()s (web-standalone.js:304-307) vs. console-only in web-app.