Draft
Conversation
🚧 :wip:
```
sequenceDiagram
participant UI as UI Thread
participant MT as Message Transporter
participant WT as Background Thread
participant SM as State Manager
UI->>MT: User Event (e.g., click)
MT->>WT: Forward Event
WT->>SM: Process Logic/Update State
SM->>WT: State Update / Effects
WT->>MT: Diff (make patches)
MT->>UI: Forward patches
UI->>UI: DOM Update
```
This PR splits up processing of events and DOM operations across both background and main threads.
This should give us access to native modules in `swift` / `kotlin`, etc.
This works by abstracting out all DOM operations during diffing for
transfer via Web Worker to the MTS from the BTS. Much of this has
already been incorporated into miso so we just need to wire it up.
- [x] Define `PATCH` protocol between BTS and MTS for DOM and event messages.
- [ ] Implement `InsertBefore`
- [ ] Implement `SwapDOMRefs`
- [x] Implement `CreateElement`
- [x] Implement `CreateElementNS`
- [ ] Implement `CreateTextNode`
- [ ] Implement `SetAttribute`
- [ ] Implement `SetAttributeNS`
- [ ] Implement `AppendChild`
- [ ] Implement `RemoveChild`
- [ ] Implement `ReplaceChild`
- [ ] Implement `RemoveAttribute`
- [ ] Implement `SetTextContent`
- [ ] Implement `SetInlineStyle`
- [ ] Implement `MountComponent`
- [ ] Implement `UnmountComponent`
- [ ] Implement `ModelHydration`
- [ ] Implement `AddClass`
- [ ] Implement `RemoveClass`
- [x] Implement `AddEventListeners`
- [ ] Implement `ProcessEvent` (must be done in `miso`)
- [ ] Implement `Flush`
- [ ] Use `ReactLynx` plugin (does proper code splitting on designed `'main thread'` events).
Adding Main Thread Events support is optional (for now) and can be
implemented later. This requires the BG thread to deliver events
to the main thread on app load (since they're defined in Haskell and not JS).
Some additional work will need to be done in `miso` to abstract out
event delegation into the `EventContext`.
We'll also need to upstream the protocol defined in `miso-lynx` back
into `miso` and have `miso-lynx` consume it via `npm` (once its stable).
a65c506 to
c3f4bb8
Compare
Member
Author
dc8d96e to
41c66c6
Compare
341f2fb to
69d4f42
Compare
For some reason only 'background only' directives are working for code splitting, "lexical errors" occur with `'main thread'` directive.
Member
Author
Change updateModel to return Effect instead of Transition
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.

Incorporate dual-thread architecture 🍜 🐈
Intro 🧵🧵
This PR splits up processing of events and DOM operations across both background and main threads. This should give us access to native modules in
swift/kotlinvia the BTS.This works by abstracting out all DOM operations during diffing for transfer via Web Worker to the MTS from the BTS. It also splits up event delegation to occur between both MTS and BTS threads (for events marked as background-only specifically). The patch infrastructure has already been added into
misoso we just need to consume it and pass messages via the Web Workers.Architecture 🏗️
sequenceDiagram participant MTS as MTS participant BTS as BTS participant MISO as Miso Runtime MISO->>BTS: Initialize Component tree BTS->>MTS: Receive BTS + MTS events MTS->>MTS: Register events BTS->>MTS: Component mount / model hydration BTS->>MTS: Initial draw (Patches) MTS->>MTS: DOM update MTS->>MTS: Receive / Process MTS Event MTS->>MTS: Receive BTS Event MTS->>BTS: Forward BTS Event (e.g., tap) BTS->>MISO: Update State / Perform Effects MISO->>MISO: Native module access MISO->>BTS: Diff + Create Patches BTS->>MTS: Forward Patches MTS->>MTS: DOM UpdateTODO 🚧
PATCHprotocol between BTS and MTS for DOM, Event, Component model hydration.drawingContext+eventContextforBTS&MTS.InsertBeforeSwapDOMRefsCreateElementCreateElementNSCreateTextNodeSetAttributeSetAttributeNSAppendChildRemoveChildReplaceChildRemoveAttributeSetTextContentSetInlineStyleFlushAddClassRemoveClassAddEventListenersMountComponentUnmountComponentModelHydrationmisoReactLynxplugin (does proper code splitting on designated'main thread'events).globalThis.patchesandglobalThis.nodeIdonBTSmiso.drawingContext = patchDrawingContexton BTSMTS&BTS).captureProcessEvent(viadelegatorimp.)NodeIdwrapper over each element in event stack.delegateEventmisoto addmount/unmountFFI calls forComponentContext<T>, and for model hydration. No-op inmiso, but used inlynxformodelhydration. Also required for main thread events.requestAnimationFrameintoDrawingContext<T>(BTS shouldn't rAF).Component)__CreateComponentto populatecomponentsmap.Etc.
Adding Main Thread Events can be implemented later (not required for access to native modules). This requires the BTS to deliver events to the main thread on app load (since they're defined in Haskell and not JS).
Some additional work can be done in
misoto abstract out event delegation into theEventContext.We'll also need to upstream the protocol defined in
miso-lynxback intomisoand havemiso-lynxconsume it vianpm(once stable).Considerations
nodeIdtoBTSfor all subsequent draws. This might be more performant and necessary for IFR.