packages feed

miso 1.10.0.0 → 1.11.0.0

raw patch · 13 files changed

+508/−205 lines, 13 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Miso: mailAncestors :: ToJSON message => message -> Effect parent props model action
+ Miso.Effect: [_componentInfoProps] :: ComponentInfo parent props -> props
+ Miso.Effect: componentInfoProps :: Lens (ComponentInfo parent props) props
+ Miso.Effect: getProps :: MonadReader (ComponentInfo parent props) m => m props
+ Miso.Effect: props :: Lens (ComponentInfo parent props) props
+ Miso.Runtime.Internal: [_componentProps] :: ComponentState parent props model action -> props
+ Miso.Types: mountWithProps :: (Eq child, Eq props) => props -> Component parent props child action -> View parent a
+ Miso.Types: mountWithProps_ :: (Eq child, Eq props) => MisoString -> props -> Component parent props child action -> View parent a
- Miso: (+>) :: Eq child => MisoString -> Component model child action -> View model a
+ Miso: (+>) :: forall child childAction model action. Eq child => MisoString -> Component model () child childAction -> View model action
- Miso: Component :: model -> Maybe (IO model) -> (action -> Effect parent model action) -> (model -> View model action) -> [Sub action] -> [CSS] -> [JS] -> Maybe MountPoint -> LogLevel -> (Value -> Maybe action) -> [Binding parent model] -> Bool -> Maybe action -> Maybe action -> Component parent model action
+ Miso: Component :: model -> Maybe (IO model) -> (action -> Effect parent props model action) -> (props -> model -> View model action) -> [Sub action] -> [CSS] -> [JS] -> Maybe MountPoint -> LogLevel -> (Value -> Maybe action) -> [Binding parent model] -> Bool -> Maybe action -> Maybe action -> Component parent props model action
- Miso: [bindings] :: Component parent model action -> [Binding parent model]
+ Miso: [bindings] :: Component parent props model action -> [Binding parent model]
- Miso: [eventPropagation] :: Component parent model action -> Bool
+ Miso: [eventPropagation] :: Component parent props model action -> Bool
- Miso: [hydrateModel] :: Component parent model action -> Maybe (IO model)
+ Miso: [hydrateModel] :: Component parent props model action -> Maybe (IO model)
- Miso: [logLevel] :: Component parent model action -> LogLevel
+ Miso: [logLevel] :: Component parent props model action -> LogLevel
- Miso: [mailbox] :: Component parent model action -> Value -> Maybe action
+ Miso: [mailbox] :: Component parent props model action -> Value -> Maybe action
- Miso: [model] :: Component parent model action -> model
+ Miso: [model] :: Component parent props model action -> model
- Miso: [mountPoint] :: Component parent model action -> Maybe MountPoint
+ Miso: [mountPoint] :: Component parent props model action -> Maybe MountPoint
- Miso: [mount] :: Component parent model action -> Maybe action
+ Miso: [mount] :: Component parent props model action -> Maybe action
- Miso: [scripts] :: Component parent model action -> [JS]
+ Miso: [scripts] :: Component parent props model action -> [JS]
- Miso: [styles] :: Component parent model action -> [CSS]
+ Miso: [styles] :: Component parent props model action -> [CSS]
- Miso: [subs] :: Component parent model action -> [Sub action]
+ Miso: [subs] :: Component parent props model action -> [Sub action]
- Miso: [unmount] :: Component parent model action -> Maybe action
+ Miso: [unmount] :: Component parent props model action -> Maybe action
- Miso: [update] :: Component parent model action -> action -> Effect parent model action
+ Miso: [update] :: Component parent props model action -> action -> Effect parent props model action
- Miso: [view] :: Component parent model action -> model -> View model action
+ Miso: [view] :: Component parent props model action -> props -> model -> View model action
- Miso: batch :: [IO action] -> Effect parent model action
+ Miso: batch :: [IO action] -> Effect parent props model action
- Miso: broadcast :: (Eq model, ToJSON message) => message -> Effect parent model action
+ Miso: broadcast :: (Eq model, ToJSON message) => message -> Effect parent props model action
- Miso: component :: model -> (action -> Effect parent model action) -> (model -> View model action) -> Component parent model action
+ Miso: component :: model -> (action -> Effect parent props model action) -> (props -> model -> View model action) -> Component parent props model action
- Miso: data Component parent model action
+ Miso: data Component parent props model action
- Miso: for :: Foldable f => IO (f action) -> Effect parent model action
+ Miso: for :: Foldable f => IO (f action) -> Effect parent props model action
- Miso: io :: IO action -> Effect parent model action
+ Miso: io :: IO action -> Effect parent props model action
- Miso: io_ :: IO () -> Effect parent model action
+ Miso: io_ :: IO () -> Effect parent props model action
- Miso: issue :: action -> Effect parent model action
+ Miso: issue :: action -> Effect parent props model action
- Miso: mailChildren :: ToJSON message => message -> Effect parent model action
+ Miso: mailChildren :: ToJSON message => message -> Effect parent props model action
- Miso: mailParent :: ToJSON message => message -> Effect parent model action
+ Miso: mailParent :: ToJSON message => message -> Effect parent props model action
- Miso: mount_ :: Eq child => Component model child a -> View model action
+ Miso: mount_ :: Eq child => Component parent () child childAction -> View parent action
- Miso: parent :: (parent -> action) -> action -> Effect parent model action
+ Miso: parent :: (parent -> action) -> action -> Effect parent props model action
- Miso: startSub :: ToMisoString subKey => subKey -> Sub action -> Effect parent model action
+ Miso: startSub :: ToMisoString subKey => subKey -> Sub action -> Effect parent props model action
- Miso: stopSub :: ToMisoString subKey => subKey -> Effect parent model action
+ Miso: stopSub :: ToMisoString subKey => subKey -> Effect parent props model action
- Miso: sync :: IO action -> Effect parent model action
+ Miso: sync :: IO action -> Effect parent props model action
- Miso: sync_ :: IO () -> Effect parent model action
+ Miso: sync_ :: IO () -> Effect parent props model action
- Miso: type App model action = Component ROOT model action
+ Miso: type App model action = Component ROOT () model action
- Miso: vcomp :: model -> (action -> Effect parent model action) -> (model -> View model action) -> Component parent model action
+ Miso: vcomp :: model -> (action -> Effect parent props model action) -> (props -> model -> View model action) -> Component parent props model action
- Miso: withSink :: (Sink action -> IO ()) -> Effect parent model action
+ Miso: withSink :: (Sink action -> IO ()) -> Effect parent props model action
- Miso.Effect: (#>) :: IO action -> model -> Effect parent model action
+ Miso.Effect: (#>) :: IO action -> model -> Effect parent props model action
- Miso.Effect: (<#) :: model -> IO action -> Effect parent model action
+ Miso.Effect: (<#) :: model -> IO action -> Effect parent props model action
- Miso.Effect: ComponentInfo :: ComponentId -> ComponentId -> DOMRef -> ComponentInfo parent
+ Miso.Effect: ComponentInfo :: ComponentId -> ComponentId -> DOMRef -> props -> ComponentInfo parent props
- Miso.Effect: [_componentInfoDOMRef] :: ComponentInfo parent -> DOMRef
+ Miso.Effect: [_componentInfoDOMRef] :: ComponentInfo parent props -> DOMRef
- Miso.Effect: [_componentInfoId] :: ComponentInfo parent -> ComponentId
+ Miso.Effect: [_componentInfoId] :: ComponentInfo parent props -> ComponentId
- Miso.Effect: [_componentInfoParentId] :: ComponentInfo parent -> ComponentId
+ Miso.Effect: [_componentInfoParentId] :: ComponentInfo parent props -> ComponentId
- Miso.Effect: afterAll :: IO () -> Effect parent model action -> Effect parent model action
+ Miso.Effect: afterAll :: IO () -> Effect parent props model action -> Effect parent props model action
- Miso.Effect: batch :: [IO action] -> Effect parent model action
+ Miso.Effect: batch :: [IO action] -> Effect parent props model action
- Miso.Effect: batch_ :: [IO ()] -> Effect parent model action
+ Miso.Effect: batch_ :: [IO ()] -> Effect parent props model action
- Miso.Effect: beforeAll :: IO () -> Effect parent model action -> Effect parent model action
+ Miso.Effect: beforeAll :: IO () -> Effect parent props model action -> Effect parent props model action
- Miso.Effect: componentInfoDOMRef :: Lens (ComponentInfo parent) DOMRef
+ Miso.Effect: componentInfoDOMRef :: Lens (ComponentInfo parent props) DOMRef
- Miso.Effect: componentInfoId :: Lens (ComponentInfo parent) ComponentId
+ Miso.Effect: componentInfoId :: Lens (ComponentInfo parent props) ComponentId
- Miso.Effect: componentInfoParentId :: Lens (ComponentInfo parent) ComponentId
+ Miso.Effect: componentInfoParentId :: Lens (ComponentInfo parent props) ComponentId
- Miso.Effect: data ComponentInfo parent
+ Miso.Effect: data ComponentInfo parent props
- Miso.Effect: for :: Foldable f => IO (f action) -> Effect parent model action
+ Miso.Effect: for :: Foldable f => IO (f action) -> Effect parent props model action
- Miso.Effect: io :: IO action -> Effect parent model action
+ Miso.Effect: io :: IO action -> Effect parent props model action
- Miso.Effect: io_ :: IO () -> Effect parent model action
+ Miso.Effect: io_ :: IO () -> Effect parent props model action
- Miso.Effect: issue :: action -> Effect parent model action
+ Miso.Effect: issue :: action -> Effect parent props model action
- Miso.Effect: mkComponentInfo :: ComponentId -> ComponentId -> DOMRef -> ComponentInfo parent
+ Miso.Effect: mkComponentInfo :: ComponentId -> ComponentId -> DOMRef -> props -> ComponentInfo parent props
- Miso.Effect: modifyAllIO :: (IO () -> IO ()) -> Effect parent model action -> Effect parent model action
+ Miso.Effect: modifyAllIO :: (IO () -> IO ()) -> Effect parent props model action -> Effect parent props model action
- Miso.Effect: noop :: action -> Effect parent model action
+ Miso.Effect: noop :: action -> Effect parent props model action
- Miso.Effect: runEffect :: Effect parent model action -> ComponentInfo parent -> model -> (model, [Schedule action])
+ Miso.Effect: runEffect :: Effect parent props model action -> ComponentInfo parent props -> model -> (model, [Schedule action])
- Miso.Effect: sync :: IO action -> Effect parent model action
+ Miso.Effect: sync :: IO action -> Effect parent props model action
- Miso.Effect: sync_ :: IO () -> Effect parent model action
+ Miso.Effect: sync_ :: IO () -> Effect parent props model action
- Miso.Effect: type Effect parent model action = RWS ComponentInfo parent [Schedule action] model ()
+ Miso.Effect: type Effect parent props model action = RWS ComponentInfo parent props [Schedule action] model ()
- Miso.Effect: withSink :: (Sink action -> IO ()) -> Effect parent model action
+ Miso.Effect: withSink :: (Sink action -> IO ()) -> Effect parent props model action
- Miso.EventSource: close :: EventSource -> Effect parent model action
+ Miso.EventSource: close :: EventSource -> Effect parent props model action
- Miso.EventSource: connectJSON :: FromJSON value => URL -> (EventSource -> action) -> (value -> action) -> (MisoString -> action) -> Effect parent model action
+ Miso.EventSource: connectJSON :: FromJSON value => URL -> (EventSource -> action) -> (value -> action) -> (MisoString -> action) -> Effect parent props model action
- Miso.EventSource: connectText :: URL -> (EventSource -> action) -> (MisoString -> action) -> (MisoString -> action) -> Effect parent model action
+ Miso.EventSource: connectText :: URL -> (EventSource -> action) -> (MisoString -> action) -> (MisoString -> action) -> Effect parent props model action
- Miso.EventSource: socketState :: WebSocket -> (SocketState -> action) -> Effect parent model action
+ Miso.EventSource: socketState :: WebSocket -> (SocketState -> action) -> Effect parent props model action
- Miso.Fetch: getArrayBuffer :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response ArrayBuffer -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: getArrayBuffer :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response ArrayBuffer -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: getBlob :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response Blob -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: getBlob :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response Blob -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: getFormData :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response FormData -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: getFormData :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response FormData -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: getJSON :: (FromJSON body, FromJSVal error) => MisoString -> [(MisoString, MisoString)] -> (Response body -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: getJSON :: (FromJSON body, FromJSVal error) => MisoString -> [(MisoString, MisoString)] -> (Response body -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: getText :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response MisoString -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: getText :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response MisoString -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: getUint8Array :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response Uint8Array -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: getUint8Array :: FromJSVal error => MisoString -> [(MisoString, MisoString)] -> (Response Uint8Array -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: postArrayBuffer :: FromJSVal error => MisoString -> ArrayBuffer -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: postArrayBuffer :: FromJSVal error => MisoString -> ArrayBuffer -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: postBlob :: FromJSVal error => MisoString -> Blob -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: postBlob :: FromJSVal error => MisoString -> Blob -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: postFormData :: FromJSVal error => MisoString -> FormData -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: postFormData :: FromJSVal error => MisoString -> FormData -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: postImage :: FromJSVal error => MisoString -> Image -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: postImage :: FromJSVal error => MisoString -> Image -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: postJSON :: (FromJSVal error, ToJSON body) => MisoString -> body -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: postJSON :: (FromJSVal error, ToJSON body) => MisoString -> body -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: postJSON' :: (FromJSVal error, ToJSON body, FromJSON return) => MisoString -> body -> [(MisoString, MisoString)] -> (Response return -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: postJSON' :: (FromJSVal error, ToJSON body, FromJSON return) => MisoString -> body -> [(MisoString, MisoString)] -> (Response return -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: postText :: FromJSVal error => MisoString -> MisoString -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: postText :: FromJSVal error => MisoString -> MisoString -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: postUint8Array :: FromJSVal error => MisoString -> Uint8Array -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: postUint8Array :: FromJSVal error => MisoString -> Uint8Array -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: putArrayBuffer :: FromJSVal error => MisoString -> ArrayBuffer -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: putArrayBuffer :: FromJSVal error => MisoString -> ArrayBuffer -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: putBlob :: FromJSVal error => MisoString -> Blob -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: putBlob :: FromJSVal error => MisoString -> Blob -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: putFormData :: FromJSVal error => MisoString -> FormData -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: putFormData :: FromJSVal error => MisoString -> FormData -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: putImage :: FromJSVal error => MisoString -> Image -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: putImage :: FromJSVal error => MisoString -> Image -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: putJSON :: (FromJSVal error, ToJSON body) => MisoString -> body -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: putJSON :: (FromJSVal error, ToJSON body) => MisoString -> body -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: putText :: FromJSVal error => MisoString -> MisoString -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: putText :: FromJSVal error => MisoString -> MisoString -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Fetch: putUint8Array :: FromJSVal error => MisoString -> Uint8Array -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent model action
+ Miso.Fetch: putUint8Array :: FromJSVal error => MisoString -> Uint8Array -> [(MisoString, MisoString)] -> (Response () -> action) -> (Response error -> action) -> Effect parent props model action
- Miso.Navigator: copyClipboard :: MisoString -> action -> (JSVal -> action) -> Effect parent model action
+ Miso.Navigator: copyClipboard :: MisoString -> action -> (JSVal -> action) -> Effect parent props model action
- Miso.Navigator: geolocation :: (Geolocation -> action) -> (GeolocationError -> action) -> Effect parent model action
+ Miso.Navigator: geolocation :: (Geolocation -> action) -> (GeolocationError -> action) -> Effect parent props model action
- Miso.Navigator: getUserMedia :: UserMedia -> (Stream -> action) -> (JSVal -> action) -> Effect parent model action
+ Miso.Navigator: getUserMedia :: UserMedia -> (Stream -> action) -> (JSVal -> action) -> Effect parent props model action
- Miso.Navigator: isOnLine :: (Bool -> action) -> Effect parent model action
+ Miso.Navigator: isOnLine :: (Bool -> action) -> Effect parent props model action
- Miso.PubSub: subscribe :: FromJSON message => Topic message -> (message -> action) -> (MisoString -> action) -> Effect parent model action
+ Miso.PubSub: subscribe :: FromJSON message => Topic message -> (message -> action) -> (MisoString -> action) -> Effect parent props model action
- Miso.PubSub: unsubscribe :: Topic message -> Effect parent model action
+ Miso.PubSub: unsubscribe :: Topic message -> Effect parent props model action
- Miso.Runtime.Internal: ComponentState :: ComponentId -> ComponentId -> IORef (Map MisoString ThreadId) -> DOMRef -> IORef VTree -> (action -> IO ()) -> model -> Bool -> [DOMRef] -> Events -> [Binding parent model] -> (Value -> Maybe action) -> (model -> IO ()) -> (model -> model -> Bool) -> ([action] -> model -> IntMap (ComponentState parent model action) -> (IntMap (ComponentState parent model action), model, [Schedule action], ComponentIds)) -> Map MisoString (Value -> IO ()) -> ComponentIds -> ComponentState parent model action
+ Miso.Runtime.Internal: ComponentState :: ComponentId -> ComponentId -> props -> IORef (Map MisoString ThreadId) -> DOMRef -> IORef VTree -> (action -> IO ()) -> model -> Bool -> [DOMRef] -> Events -> [Binding parent model] -> (Value -> Maybe action) -> (model -> IO ()) -> (model -> model -> Bool) -> ([action] -> model -> IntMap (ComponentState parent props model action) -> props -> (IntMap (ComponentState parent props model action), model, [Schedule action], ComponentIds)) -> Map MisoString (Value -> IO ()) -> ComponentIds -> ComponentState parent props model action
- Miso.Runtime.Internal: [_componentApplyActions] :: ComponentState parent model action -> [action] -> model -> IntMap (ComponentState parent model action) -> (IntMap (ComponentState parent model action), model, [Schedule action], ComponentIds)
+ Miso.Runtime.Internal: [_componentApplyActions] :: ComponentState parent props model action -> [action] -> model -> IntMap (ComponentState parent props model action) -> props -> (IntMap (ComponentState parent props model action), model, [Schedule action], ComponentIds)
- Miso.Runtime.Internal: [_componentBindings] :: ComponentState parent model action -> [Binding parent model]
+ Miso.Runtime.Internal: [_componentBindings] :: ComponentState parent props model action -> [Binding parent model]
- Miso.Runtime.Internal: [_componentChildren] :: ComponentState parent model action -> ComponentIds
+ Miso.Runtime.Internal: [_componentChildren] :: ComponentState parent props model action -> ComponentIds
- Miso.Runtime.Internal: [_componentDOMRef] :: ComponentState parent model action -> DOMRef
+ Miso.Runtime.Internal: [_componentDOMRef] :: ComponentState parent props model action -> DOMRef
- Miso.Runtime.Internal: [_componentDraw] :: ComponentState parent model action -> model -> IO ()
+ Miso.Runtime.Internal: [_componentDraw] :: ComponentState parent props model action -> model -> IO ()
- Miso.Runtime.Internal: [_componentEvents] :: ComponentState parent model action -> Events
+ Miso.Runtime.Internal: [_componentEvents] :: ComponentState parent props model action -> Events
- Miso.Runtime.Internal: [_componentId] :: ComponentState parent model action -> ComponentId
+ Miso.Runtime.Internal: [_componentId] :: ComponentState parent props model action -> ComponentId
- Miso.Runtime.Internal: [_componentIsDirty] :: ComponentState parent model action -> Bool
+ Miso.Runtime.Internal: [_componentIsDirty] :: ComponentState parent props model action -> Bool
- Miso.Runtime.Internal: [_componentMailbox] :: ComponentState parent model action -> Value -> Maybe action
+ Miso.Runtime.Internal: [_componentMailbox] :: ComponentState parent props model action -> Value -> Maybe action
- Miso.Runtime.Internal: [_componentModelDirty] :: ComponentState parent model action -> model -> model -> Bool
+ Miso.Runtime.Internal: [_componentModelDirty] :: ComponentState parent props model action -> model -> model -> Bool
- Miso.Runtime.Internal: [_componentModel] :: ComponentState parent model action -> model
+ Miso.Runtime.Internal: [_componentModel] :: ComponentState parent props model action -> model
- Miso.Runtime.Internal: [_componentParentId] :: ComponentState parent model action -> ComponentId
+ Miso.Runtime.Internal: [_componentParentId] :: ComponentState parent props model action -> ComponentId
- Miso.Runtime.Internal: [_componentScripts] :: ComponentState parent model action -> [DOMRef]
+ Miso.Runtime.Internal: [_componentScripts] :: ComponentState parent props model action -> [DOMRef]
- Miso.Runtime.Internal: [_componentSink] :: ComponentState parent model action -> action -> IO ()
+ Miso.Runtime.Internal: [_componentSink] :: ComponentState parent props model action -> action -> IO ()
- Miso.Runtime.Internal: [_componentSubThreads] :: ComponentState parent model action -> IORef (Map MisoString ThreadId)
+ Miso.Runtime.Internal: [_componentSubThreads] :: ComponentState parent props model action -> IORef (Map MisoString ThreadId)
- Miso.Runtime.Internal: [_componentTopics] :: ComponentState parent model action -> Map MisoString (Value -> IO ())
+ Miso.Runtime.Internal: [_componentTopics] :: ComponentState parent props model action -> Map MisoString (Value -> IO ())
- Miso.Runtime.Internal: [_componentVTree] :: ComponentState parent model action -> IORef VTree
+ Miso.Runtime.Internal: [_componentVTree] :: ComponentState parent props model action -> IORef VTree
- Miso.Runtime.Internal: components :: IORef (IntMap (ComponentState parent model action))
+ Miso.Runtime.Internal: components :: IORef (IntMap (ComponentState parent props model action))
- Miso.Runtime.Internal: data ComponentState parent model action
+ Miso.Runtime.Internal: data ComponentState parent props model action
- Miso.Types: (+>) :: Eq child => MisoString -> Component model child action -> View model a
+ Miso.Types: (+>) :: forall child childAction model action. Eq child => MisoString -> Component model () child childAction -> View model action
- Miso.Types: Component :: model -> Maybe (IO model) -> (action -> Effect parent model action) -> (model -> View model action) -> [Sub action] -> [CSS] -> [JS] -> Maybe MountPoint -> LogLevel -> (Value -> Maybe action) -> [Binding parent model] -> Bool -> Maybe action -> Maybe action -> Component parent model action
+ Miso.Types: Component :: model -> Maybe (IO model) -> (action -> Effect parent props model action) -> (props -> model -> View model action) -> [Sub action] -> [CSS] -> [JS] -> Maybe MountPoint -> LogLevel -> (Value -> Maybe action) -> [Binding parent model] -> Bool -> Maybe action -> Maybe action -> Component parent props model action
- Miso.Types: SomeComponent :: Component parent model action -> SomeComponent parent
+ Miso.Types: SomeComponent :: props -> Component parent props model action -> SomeComponent parent
- Miso.Types: [bindings] :: Component parent model action -> [Binding parent model]
+ Miso.Types: [bindings] :: Component parent props model action -> [Binding parent model]
- Miso.Types: [eventPropagation] :: Component parent model action -> Bool
+ Miso.Types: [eventPropagation] :: Component parent props model action -> Bool
- Miso.Types: [hydrateModel] :: Component parent model action -> Maybe (IO model)
+ Miso.Types: [hydrateModel] :: Component parent props model action -> Maybe (IO model)
- Miso.Types: [logLevel] :: Component parent model action -> LogLevel
+ Miso.Types: [logLevel] :: Component parent props model action -> LogLevel
- Miso.Types: [mailbox] :: Component parent model action -> Value -> Maybe action
+ Miso.Types: [mailbox] :: Component parent props model action -> Value -> Maybe action
- Miso.Types: [model] :: Component parent model action -> model
+ Miso.Types: [model] :: Component parent props model action -> model
- Miso.Types: [mountPoint] :: Component parent model action -> Maybe MountPoint
+ Miso.Types: [mountPoint] :: Component parent props model action -> Maybe MountPoint
- Miso.Types: [mount] :: Component parent model action -> Maybe action
+ Miso.Types: [mount] :: Component parent props model action -> Maybe action
- Miso.Types: [scripts] :: Component parent model action -> [JS]
+ Miso.Types: [scripts] :: Component parent props model action -> [JS]
- Miso.Types: [styles] :: Component parent model action -> [CSS]
+ Miso.Types: [styles] :: Component parent props model action -> [CSS]
- Miso.Types: [subs] :: Component parent model action -> [Sub action]
+ Miso.Types: [subs] :: Component parent props model action -> [Sub action]
- Miso.Types: [unmount] :: Component parent model action -> Maybe action
+ Miso.Types: [unmount] :: Component parent props model action -> Maybe action
- Miso.Types: [update] :: Component parent model action -> action -> Effect parent model action
+ Miso.Types: [update] :: Component parent props model action -> action -> Effect parent props model action
- Miso.Types: [view] :: Component parent model action -> model -> View model action
+ Miso.Types: [view] :: Component parent props model action -> props -> model -> View model action
- Miso.Types: component :: model -> (action -> Effect parent model action) -> (model -> View model action) -> Component parent model action
+ Miso.Types: component :: model -> (action -> Effect parent props model action) -> (props -> model -> View model action) -> Component parent props model action
- Miso.Types: data Component parent model action
+ Miso.Types: data Component parent props model action
- Miso.Types: mount_ :: Eq child => Component model child a -> View model action
+ Miso.Types: mount_ :: Eq child => Component parent () child childAction -> View parent action
- Miso.Types: type App model action = Component ROOT model action
+ Miso.Types: type App model action = Component ROOT () model action
- Miso.Types: vcomp :: model -> (action -> Effect parent model action) -> (model -> View model action) -> Component parent model action
+ Miso.Types: vcomp :: model -> (action -> Effect parent props model action) -> (props -> model -> View model action) -> Component parent props model action
- Miso.WebSocket: close :: WebSocket -> Effect parent model action
+ Miso.WebSocket: close :: WebSocket -> Effect parent props model action
- Miso.WebSocket: connect :: FromJSON json => URL -> (WebSocket -> action) -> (Closed -> action) -> (Payload json -> action) -> (MisoString -> action) -> Effect parent model action
+ Miso.WebSocket: connect :: FromJSON json => URL -> (WebSocket -> action) -> (Closed -> action) -> (Payload json -> action) -> (MisoString -> action) -> Effect parent props model action
- Miso.WebSocket: connectArrayBuffer :: URL -> (WebSocket -> action) -> (Closed -> action) -> (ArrayBuffer -> action) -> (MisoString -> action) -> Effect parent model action
+ Miso.WebSocket: connectArrayBuffer :: URL -> (WebSocket -> action) -> (Closed -> action) -> (ArrayBuffer -> action) -> (MisoString -> action) -> Effect parent props model action
- Miso.WebSocket: connectBLOB :: URL -> (WebSocket -> action) -> (Closed -> action) -> (Blob -> action) -> (MisoString -> action) -> Effect parent model action
+ Miso.WebSocket: connectBLOB :: URL -> (WebSocket -> action) -> (Closed -> action) -> (Blob -> action) -> (MisoString -> action) -> Effect parent props model action
- Miso.WebSocket: connectJSON :: FromJSON json => URL -> (WebSocket -> action) -> (Closed -> action) -> (json -> action) -> (MisoString -> action) -> Effect parent model action
+ Miso.WebSocket: connectJSON :: FromJSON json => URL -> (WebSocket -> action) -> (Closed -> action) -> (json -> action) -> (MisoString -> action) -> Effect parent props model action
- Miso.WebSocket: connectText :: URL -> (WebSocket -> action) -> (Closed -> action) -> (MisoString -> action) -> (MisoString -> action) -> Effect parent model action
+ Miso.WebSocket: connectText :: URL -> (WebSocket -> action) -> (Closed -> action) -> (MisoString -> action) -> (MisoString -> action) -> Effect parent props model action
- Miso.WebSocket: sendArrayBuffer :: WebSocket -> ArrayBuffer -> Effect parent model action
+ Miso.WebSocket: sendArrayBuffer :: WebSocket -> ArrayBuffer -> Effect parent props model action
- Miso.WebSocket: sendBLOB :: WebSocket -> Blob -> Effect parent model action
+ Miso.WebSocket: sendBLOB :: WebSocket -> Blob -> Effect parent props model action
- Miso.WebSocket: sendJSON :: ToJSON json => WebSocket -> json -> Effect parent model action
+ Miso.WebSocket: sendJSON :: ToJSON json => WebSocket -> json -> Effect parent props model action
- Miso.WebSocket: sendText :: WebSocket -> MisoString -> Effect parent model action
+ Miso.WebSocket: sendText :: WebSocket -> MisoString -> Effect parent props model action
- Miso.WebSocket: socketState :: WebSocket -> (SocketState -> action) -> Effect parent model action
+ Miso.WebSocket: socketState :: WebSocket -> (SocketState -> action) -> Effect parent props model action

Files

README.md view
@@ -200,7 +200,7 @@ app = vcomp 0 updateModel viewModel ---------------------------------------------------------------------------- -- | Updates model, optionally introduces side effects-updateModel :: Action -> Effect parent Int Action+updateModel :: Action -> Effect parent props Int Action updateModel = \case   AddOne -> this += 1   SubtractOne -> this -= 1@@ -209,8 +209,8 @@     consoleLog "Hello World" ---------------------------------------------------------------------------- -- | Constructs a virtual DOM from a model-viewModel :: Int -> View Int Action-viewModel x = vfrag+viewModel :: () -> Int -> View Int Action+viewModel _props x = vfrag     [ H.button_ [ H.onClick AddOne ] [ text "+" ]     , text (ms x)     , H.button_ [ H.onClick SubtractOne ] [ text "-" ]
js/miso.js view
@@ -282,6 +282,8 @@       n.componentId = c.componentId;       if (c.child)         c.child.parent = n;+      if (n.diffProps)+        n.diffProps();       return;     }     replace(c, n, parent, context);
js/miso.prod.js view
@@ -1,1 +1,1 @@-var m="1.9.0.0";function y(U,z){var G=function(){var H=document.getElementById(U);if(H&&H.focus)H.focus()};z>0?setTimeout(G,z):G()}function h(U,z){var G=function(){var H=document.getElementById(U);if(H&&H.blur)H.blur()};z>0?setTimeout(G,z):G()}function u(U,z){var G=function(){var H=document.getElementById(U);if(H&&typeof H.select==="function")H.select()};z>0?setTimeout(G,z):G()}function g(U,z,G,H){var K=function(){var Q=document.getElementById(U);if(Q&&typeof Q.setSelectionRange==="function")Q.setSelectionRange(z,G,"none")};H>0?setTimeout(K,H):K()}function v(U,z,G,H,K,Q,X){var Y={method:z,headers:H};if(G)Y.body=G;let $={},_=null;try{fetch(U,Y).then((Z)=>{_=Z.status;for(let[B,S]of Z.headers)$[B]=S;if(!Z.ok)throw Error(Z.statusText);if(X=="json")return Z.json();else if(X=="text")return Z.text();else if(X==="arrayBuffer")return Z.arrayBuffer();else if(X==="blob")return Z.blob();else if(X==="bytes")return Z.bytes();else if(X==="formData")return Z.formData();else if(X==="none")return K({error:null,body:null,headers:$,status:_})}).then((Z)=>K({error:null,body:Z,headers:$,status:_})).catch((Z)=>Q({error:null,body:Z,headers:$,status:_}))}catch(Z){Q({body:null,error:Z.message,headers:$,status:_})}}function l(U,z,G,H,K,Q,X,Y,$){try{let _=new WebSocket(U);return _.onopen=function(){z()},_.onclose=function(Z){G(Z)},_.onerror=function(Z){console.error(Z),Y("WebSocket error received")},_.onmessage=function(Z){if(typeof Z.data==="string")try{if($){if(H)H(Z.data);return}let B=JSON.parse(Z.data);if(K)K(B)}catch(B){if($&&H)H(Z.data);else Y(B.message)}else if(Z.data instanceof Blob){if(Q)Q(Z.data)}else if(Z.data instanceof ArrayBuffer){if(X)X(Z.data)}else console.error("Received unknown message type from WebSocket",Z),Y("Unknown message received from WebSocket")},_}catch(_){Y(_.message)}}function x(U){if(U)U.close(),U=null}function i(U,z){if(z&&U&&U.readyState===WebSocket.OPEN)U.send(z)}function d(U,z,G,H,K,Q){try{let X=new EventSource(U);return X.onopen=function(){z()},X.onerror=function(){K("EventSource error received")},X.onmessage=function(Y){try{if(Q){if(G)G(Y.data);return}let $=JSON.parse(Y.data);if(H)H($)}catch($){if(Q&&G)G(Y.data);else K($.message)}},X}catch(X){K(X.message)}}function p(U){if(U)U.close(),U=null}function a(U,z){if(!U.classList)U.classList=new Set;for(let G of z)for(let H of G.trim().split(" "))if(H)U.classList.add(H)}function s(U,z){if(!U.parent)return;z.nextSibling=U.nextSibling,z.parent=U.parent,U.parent.child=z}function r(U,z={}){let G=Object.keys(z),H=Object.values(z);return Function(...G,U)(...H)}function c(U){if(U===null||U===void 0)return 0;if(typeof U==="number")return 1;if(typeof U==="string")return 2;if(typeof U==="boolean")return 3;if(Array.isArray(U))return 4;return 5}function o(U){return function(){U|=0,U=U+2654435769|0;var z=U^U>>>15;return z=Math.imul(z,2246822507),z=z^z>>>13,z=Math.imul(z,3266489909),((z^z>>>16)>>>0)/4294967296}}function n(){let U=new Uint32Array(1);return crypto.getRandomValues(U)[0]}function t(){return Math.random()}function W(U,z){switch(U.type){case 3:for(let G of U.children)W(G,z);break;case 0:if(U.child)W(U.child,z);break;default:z(U.domRef);break}}function q(U){switch(U.type){case 3:{if(!U.children||U.children.length===0)return null;return q(U.children[0])}case 0:if(!U.child)return null;return q(U.child);default:return U.domRef}}function N(U){switch(U.type){case 3:{if(!U.children||U.children.length===0)return null;return N(U.children[U.children.length-1])}case 0:if(!U.child)return null;return N(U.child);default:return U.domRef}}function A(U,z,G,H){if(!U&&!z)return;else if(!U)D(z,G,H);else if(!z)O(U,G,H);else if(U.type===2&&z.type===2)JU(U,z,H);else if(U.type===0&&z.type===0){if(z.key===U.key){if(z.child=U.child,z.componentId=U.componentId,U.child)U.child.parent=z;return}V(U,z,G,H)}else if(U.type===3&&z.type===3)if(z.key===U.key){let K=N(U),Q=K?K.nextSibling:H.nextSibling(U);XU(U.children,z.children,G,H,Q)}else V(U,z,G,H);else if(U.type===1&&z.type===1)if(z.tag===U.tag&&z.key===U.key)z.domRef=U.domRef,QU(U,z,H);else V(U,z,G,H);else V(U,z,G,H)}function JU(U,z,G){if(U.text!==z.text)G.setTextContent(U.domRef,z.text);z.domRef=U.domRef;return}function V(U,z,G,H){if(U.type===3){let X=N(U),Y=X?X.nextSibling:H.nextSibling(U);if(O(U,G,H),Y)C(G,2,Y,z,H);else D(z,G,H);return}switch(U.type){case 2:break;default:P(U);break}let K=q(U),Q=N(U);if(!K||!Q){let X=H.nextSibling(U);if(X)C(G,2,X,z,H);else D(z,G,H)}else if(K!==Q){let X=Q.nextSibling;if(W(U,(Y)=>H.removeChild(G,Y)),X)C(G,2,X,z,H);else D(z,G,H)}else C(G,1,K,z,H);switch(U.type){case 2:break;default:R(U);break}}function O(U,z,G){switch(U.type){case 2:break;case 3:for(let H of U.children)O(H,z,G);return;default:P(U);break}switch(W(U,(H)=>G.removeChild(z,H)),U.type){case 2:break;default:R(U);break}}function R(U){if(U.type===3){for(let z of U.children)if(z.type!==2)R(z);return}switch(AU(U),U.type){case 1:for(let z of U.children)if(z.type!==2)R(z);break;case 0:if(U.child&&U.child.type!==2)R(U.child);break}}function AU(U){if(U.type===1&&U.onDestroyed)U.onDestroyed();if(U.type===0)wU(U)}function BU(U){switch(U.type){case 0:break;case 1:if(U.onBeforeDestroyed)U.onBeforeDestroyed();break;default:break}}function P(U){if(U.type===3){for(let z of U.children)if(z.type!==2)P(z);return}switch(BU(U),U.type){case 1:for(let z of U.children){if(z.type===2)continue;P(z)}break;case 0:if(U.child&&U.child.type!==2)P(U.child);break}}function QU(U,z,G){NU(U?U.props:{},z.props,z.domRef,z.ns==="svg",G),SU(U?U.classList:null,z.classList,z.domRef,G),CU(U?U.css:{},z.css,z.domRef,G),XU(U?U.children:[],z.children,z.domRef,G),IU(z)}function SU(U,z,G,H){if(!U&&!z)return;if(!U){for(let K of z)H.addClass(K,G);return}if(!z){for(let K of U)H.removeClass(K,G);return}for(let K of U)if(!z.has(K))H.removeClass(K,G);for(let K of z)if(!U.has(K))H.addClass(K,G);return}function NU(U,z,G,H,K){var Q;for(let X in U)if(Q=z[X],Q===void 0)if(H||!(X in G)||X==="disabled")K.removeAttribute(G,X);else K.setAttribute(G,X,"");else{if(Q===U[X]&&X!=="checked"&&X!=="value")continue;if(H)if(X==="href")K.setAttributeNS(G,"http://www.w3.org/1999/xlink","href",Q);else K.setAttribute(G,X,Q);else if(X in G&&!(X==="list"||X==="form"))G[X]=Q;else K.setAttribute(G,X,Q)}for(let X in z){if(U&&X in U)continue;if(Q=z[X],H)if(X==="href")K.setAttributeNS(G,"http://www.w3.org/1999/xlink","href",Q);else K.setAttribute(G,X,Q);else if(X in G&&!(X==="list"||X==="form"))G[X]=z[X];else K.setAttribute(G,X,Q)}}function CU(U,z,G,H){H.setInlineStyle(U,z,G)}function EU(U,z){if(U.length===0||z.length===0)return!1;for(var G=0;G<U.length;G++)if(U[G].key===null||U[G].key===void 0)return!1;for(var G=0;G<z.length;G++)if(z[G].key===null||z[G].key===void 0)return!1;return!0}function XU(U,z,G,H,K=null){if(EU(U,z))PU(U,z,G,H,K);else for(let Q=0;Q<Math.max(z.length,U.length);Q++){let X=U[Q],Y=z[Q];if(!X&&Y)if(K)C(G,2,K,Y,H);else D(Y,G,H);else A(X,Y,G,H)}}function DU(U,z){if(U.ns==="svg")U.domRef=z.createElementNS("http://www.w3.org/2000/svg",U.tag);else if(U.ns==="mathml")U.domRef=z.createElementNS("http://www.w3.org/1998/Math/MathML",U.tag);else U.domRef=z.createElement(U.tag)}function YU(U,z,G){if(z.onCreated)z.onCreated(z.domRef)}function C(U,z,G,H,K){switch(H.type){case 2:switch(H.domRef=K.createTextNode(H.text),z){case 2:K.insertBefore(U,H.domRef,G);break;case 0:K.appendChild(U,H.domRef);break;case 1:K.replaceChild(U,H.domRef,G);break}break;case 3:for(let Q of H.children)C(U,2,G,Q,K);if(z===1&&G)K.removeChild(U,G);break;case 0:MU(U,z,G,H,K);break;case 1:if(H.onBeforeCreated)H.onBeforeCreated();if(DU(H,K),H.onCreated)H.onCreated(H.domRef);switch(QU(null,H,K),z){case 2:K.insertBefore(U,H.domRef,G);break;case 0:K.appendChild(U,H.domRef);break;case 1:K.replaceChild(U,H.domRef,G);break}break}}function IU(U){if(U.tag==="canvas"&&U.draw)U.draw(U.domRef)}function wU(U){U.unmount(U.componentId)}function MU(U,z,G,H,K){let Q=H.mount(U);H.componentId=Q.componentId,H.child=Q.componentTree,Q.componentTree.parent=H;let X=q(Q.componentTree);if(Q.componentTree.type!==0){if(z===1&&G)if(!X)K.removeChild(U,G);else if(Q.componentTree.type===3)W(Q.componentTree,(Y)=>K.insertBefore(U,Y,G)),K.removeChild(U,G);else K.replaceChild(U,X,G);else if(z===2)if(G)W(Q.componentTree,(Y)=>K.insertBefore(U,Y,G));else W(Q.componentTree,(Y)=>K.appendChild(U,Y))}}function D(U,z,G){C(z,0,null,U,G)}function KU(U,z,G,H){let K=G?q(G)??H.nextSibling(G):null;if(K)W(z,(Q)=>H.insertBefore(U,Q,K));else W(z,(Q)=>H.appendChild(U,Q))}function RU(U,z,G,H){let K=q(U),Q=q(z);if(K&&Q&&(U.type===1||U.type===2)&&(z.type===1||z.type===2)){H.swapDOMRefs(K,Q,G);return}let X=N(U),Y=X?X.nextSibling:H.nextSibling(U),$=q(z)??H.nextSibling(z);if($)W(U,(_)=>H.insertBefore(G,_,$));else W(U,(_)=>H.appendChild(G,_));if(Y)W(z,(_)=>H.insertBefore(G,_,Y));else W(z,(_)=>H.appendChild(G,_))}function PU(U,z,G,H,K=null){var Q=0,X=0,Y=U.length-1,$=z.length-1,_,Z,B,S,J,f,HU;for(;;){if(X>$&&Q>Y)break;if(Z=z[X],B=z[$],J=U[Q],S=U[Y],Q>Y){let M=(J?q(J)??H.nextSibling(J):null)??K;if(M)C(G,2,M,Z,H);else D(Z,G,H);U.splice(X,0,Z),X++}else if(X>$){_=Y;while(Y>=Q)O(U[Y--],G,H);U.splice(Q,_-Q+1);break}else if(J.key===Z.key)A(U[Q++],z[X++],G,H);else if(S.key===B.key)A(U[Y--],z[$--],G,H);else if(J.key===B.key&&Z.key===S.key)RU(S,J,G,H),FU(U,Q,Y),A(U[Q++],z[X++],G,H),A(U[Y--],z[$--],G,H);else if(J.key===B.key){let I=N(S),M=I?I.nextSibling:H.nextSibling(S);if(M)W(J,(T)=>H.insertBefore(G,T,M));else W(J,(T)=>H.appendChild(G,T));U.splice(Y,0,U.splice(Q,1)[0]),A(U[Y--],z[$--],G,H)}else if(S.key===Z.key)KU(G,S,J,H),U.splice(Q,0,U.splice(Y,1)[0]),A(U[Q++],Z,G,H),X++;else{f=!1,_=Q;while(_<=Y){if(U[_].key===Z.key){f=!0,HU=U[_];break}_++}if(f)U.splice(Q,0,U.splice(_,1)[0]),A(U[Q++],Z,G,H),KU(G,HU,U[Q],H),X++;else{let I=q(J)??H.nextSibling(J);if(I)C(G,2,I,Z,H);else D(Z,G,H);U.splice(Q++,0,Z),X++,Y++}}}}function FU(U,z,G){let H=U[z];U[z]=U[G],U[G]=H}function e(U,z,G,H,K){for(let Q of z)K.addEventListener(U,Q.name,function(X){LU(X,U,G,H,K)},Q.capture)}function LU(U,z,G,H,K){G(function(Q){if(Array.isArray(U))for(let X of U)ZU(X,Q,z,H,K);else ZU(U,Q,z,H,K)})}function ZU(U,z,G,H,K){var Q=K.getTarget(U);if(Q){let X=VU(G,Q,K);E(U,z,X,H,K)}}function VU(U,z,G){var H=[];while(!G.isEqual(U,z))if(H.unshift(z),z&&G.parentNode(z))z=G.parentNode(z);else return H;return H}function E(U,z,G,H,K){if(!G.length){if(H)console.warn('Event "'+U.type+'" did not find an event handler to dispatch on',z,U);return}else if(G.length>1){if(z.type===2)return;else if(z.type===3){for(let Q of z.children)if(F(Q,G[0],K)){E(U,Q,G,H,K);return}return}else if(z.type===0){if(!z.child){if(H)throw console.error("VComp has no child property set during event delegation",z),console.error("This means the Component has not been fully mounted, this should never happen"),Error("VComp has no .child property set during event delegation");return}return E(U,z.child,G,H,K)}else if(z.type===1){if(K.isEqual(z.domRef,G[0])){let Q=z.events.captures[U.type];if(Q){let X=Q.options;if(X.preventDefault)U.preventDefault();if(!U.captureStopped)Q.runEvent(U,z.domRef);if(X.stopPropagation)U.captureStopped=!0}G.splice(0,1);for(let X of z.children)if(F(X,G[0],K)){E(U,X,G,H,K);return}}return}}else if(z.type===0){if(z.child)E(U,z.child,G,H,K)}else if(z.type===3){for(let Q of z.children)if(F(Q,G[0],K)){E(U,Q,G,H,K);return}}else if(z.type===1){let Q=z.events.captures[U.type];if(Q&&!U.captureStopped){let Y=Q.options;if(K.isEqual(G[0],z.domRef)){if(Y.preventDefault)U.preventDefault();if(Q.runEvent(U,G[0]),Y.stopPropagation)U.captureStopped=!0}}let X=z.events.bubbles[U.type];if(X&&!U.captureStopped){let Y=X.options;if(K.isEqual(G[0],z.domRef)){if(Y.preventDefault)U.preventDefault();if(X.runEvent(U,G[0]),!Y.stopPropagation)$U(z.parent,U)}}else if(!U.captureStopped)$U(z.parent,U)}}function $U(U,z){while(U)switch(U.type){case 2:break;case 3:U=U.parent;break;case 1:let G=U.events.bubbles[z.type];if(G){let H=G.options;if(H.preventDefault)z.preventDefault();if(G.runEvent(z,U.domRef),H.stopPropagation)return}U=U.parent;break;case 0:if(!U.eventPropagation)return;U=U.parent;break}}function L(U,z){if(typeof U[0]==="object"){var G=[];for(var H=0;H<U.length;H++)G.push(L(U[H],z));return G}for(let Y of U)z=z[Y];var K;if(z instanceof Array||"length"in z&&z.localName!=="select"){K=[];for(var Q=0;Q<z.length;Q++)K.push(L([],z[Q]));return K}K={};for(var X in OU(z)){if(z.localName==="input"&&(X==="selectionDirection"||X==="selectionStart"||X==="selectionEnd"))continue;if(typeof z[X]=="string"||typeof z[X]=="number"||typeof z[X]=="boolean")K[X]=z[X]}return K}function F(U,z,G){switch(U.type){case 3:for(let H of U.children)if(F(H,z,G))return!0;return!1;case 0:return U.child?F(U.child,z,G):!1;default:return G.isEqual(U.domRef,z)}}function OU(U){var z={},G=0;do{var H=Object.getOwnPropertyNames(U);for(G=0;G<H.length;G++)z[H[G]]=null}while(U=Object.getPrototypeOf(U));return z}var j={addEventListener:(U,z,G,H)=>{U.addEventListener(z,G,H)},delegator:(U,z,G,H,K)=>{e(U,z,G,H,K)},isEqual:(U,z)=>{return U===z},getTarget:(U)=>{return U.target},parentNode:(U)=>{return U.parentNode}},_U={getInlineStyle:(U,z)=>{return U.style[z]},firstChild:(U)=>{return U.firstChild},lastChild:(U)=>{return U.lastChild},getAttribute:(U,z)=>{if(z==="class")return U.className;if(z in U)return U[z];return U.getAttribute(z)},getTag:(U)=>{return U.nodeName},getTextContent:(U)=>{return U.textContent},children:(U)=>{return U.childNodes}},WU={mountComponent:function(U,z){return},unmountComponent:function(U){return},modelHydration:function(U,z){return}},UU={nextSibling:(U)=>{let z=U.nextSibling;while(z)switch(z.type){case 0:case 3:{let G=q(z);if(G)return G;z=z.nextSibling;break}default:return z.domRef}return null},createTextNode:(U)=>{return document.createTextNode(U)},createElementNS:(U,z)=>{return document.createElementNS(U,z)},appendChild:(U,z)=>{return U.appendChild(z)},replaceChild:(U,z,G)=>{return U.replaceChild(z,G)},removeChild:(U,z)=>{return U.removeChild(z)},createElement:(U)=>{return document.createElement(U)},addClass:(U,z)=>{if(U)z.classList.add(U)},removeClass:(U,z)=>{if(U)z.classList.remove(U)},insertBefore:(U,z,G)=>{return U.insertBefore(z,G)},swapDOMRefs:(U,z,G)=>{let H=U.nextSibling;G.insertBefore(U,z),G.insertBefore(z,H);return},setInlineStyle:(U,z,G)=>{var H;for(let K in U)if(H=z[K],!H)if(K in G.style)G.style[K]="";else G.style.setProperty(K,"");else if(H!==U[K])if(K in G.style)G.style[K]=H;else G.style.setProperty(K,H);for(let K in z){if(U&&U[K])continue;if(K in G.style)G.style[K]=z[K];else G.style.setProperty(K,z[K])}return},setAttribute:(U,z,G)=>{return U.setAttribute(z,G)},setAttributeNS:(U,z,G,H)=>{return U.setAttributeNS(z,G,H)},removeAttribute:(U,z)=>{return U.removeAttribute(z)},setTextContent:(U,z)=>{U.textContent=z;return},flush:()=>{return},getHead:function(){return document.head},getRoot:function(){return document.body}};function zU(U){var z=0,G=U.length>0?[U[0]]:[];for(var H=1;H<U.length;H++){if(G[z].type===2&&U[H].type===2){G[z].text+=U[H].text;continue}G[++z]=U[H]}for(let K of G)if(K.type===3)K.children=zU(K.children);return G}function GU(U,z,G,H,K){if(!G||!z)return!1;if(z.nodeType===3)return!1;if(!b(U,G,H.firstChild(z),H,K)){if(U)console.warn("[DEBUG_HYDRATE] Could not copy DOM into virtual DOM, falling back to diff");while(H.firstChild(z))K.removeChild(z,H.lastChild(z));return!1}else if(U)console.info("[DEBUG_HYDRATE] Successfully prerendered page");return!0}function k(U,z,G){if(U)console.warn("[DEBUG_HYDRATE] VTree differed from node",z,G)}function qU(U,z){let G=N(U);return G?G.nextSibling:z}function b(U,z,G,H,K){switch(z.type){case 0:let X=z.mount(G.parentNode);if(z.componentId=X.componentId,z.child=X.componentTree,X.componentTree.parent=z,!b(U,z.child,G,H,K))return!1;break;case 3:z.children=zU(z.children);for(let $ of z.children){if(!G)return k(U,$,null),!1;if(!b(U,$,G,H,K))return!1;G=qU($,G)}break;case 2:if(G.nodeType!==3||z.text.trim()!==G.textContent.trim())return k(U,z,G),!1;z.domRef=G;break;case 1:if(G.nodeType!==1)return k(U,z,G),!1;z.domRef=G,z.children=zU(z.children),YU(G,z,K);let Y=G.firstChild;for(var Q=0;Q<z.children.length;Q++){let $=z.children[Q];if(!Y)return k(U,$,null),!1;if(!b(U,$,Y,H,K))return!1;Y=qU($,Y)}break}return!0}globalThis.miso={hydrationContext:_U,eventContext:j,drawingContext:UU,componentContext:WU,diff:A,hydrate:GU,version:m,callBlur:h,callFocus:y,callSelect:u,callSetSelectionRange:g,eventJSON:L,fetchCore:v,eventSourceConnect:d,eventSourceClose:p,websocketConnect:l,websocketClose:x,websocketSend:i,updateRef:s,inline:r,typeOf:c,mathRandom:t,getRandomValues:n,splitmix32:o,populateClass:a,delegateEvent:E,delegator:j.delegator,setDrawingContext:function(U){let z=globalThis[U].drawingContext,G=globalThis[U].eventContext,H=globalThis[U].componentContext;if(!z)console.error('Custom rendering engine ("drawingContext") is not defined at globalThis[name].drawingContext',U);if(!G)console.error('Custom event delegation ("eventContext") is not defined at globalThis[name].eventContext',U);if(!H)console.error('Custom component context ("componentContext") is not defined at globalThis[name].componentContext',U);globalThis.miso.drawingContext=z,globalThis.miso.eventContext=G,globalThis.miso.componentContext=H}};+var m="1.9.0.0";function y(U,z){var G=function(){var H=document.getElementById(U);if(H&&H.focus)H.focus()};z>0?setTimeout(G,z):G()}function h(U,z){var G=function(){var H=document.getElementById(U);if(H&&H.blur)H.blur()};z>0?setTimeout(G,z):G()}function u(U,z){var G=function(){var H=document.getElementById(U);if(H&&typeof H.select==="function")H.select()};z>0?setTimeout(G,z):G()}function g(U,z,G,H){var K=function(){var Q=document.getElementById(U);if(Q&&typeof Q.setSelectionRange==="function")Q.setSelectionRange(z,G,"none")};H>0?setTimeout(K,H):K()}function v(U,z,G,H,K,Q,X){var Y={method:z,headers:H};if(G)Y.body=G;let $={},_=null;try{fetch(U,Y).then((Z)=>{_=Z.status;for(let[B,S]of Z.headers)$[B]=S;if(!Z.ok)throw new Error(Z.statusText);if(X=="json")return Z.json();else if(X=="text")return Z.text();else if(X==="arrayBuffer")return Z.arrayBuffer();else if(X==="blob")return Z.blob();else if(X==="bytes")return Z.bytes();else if(X==="formData")return Z.formData();else if(X==="none")return K({error:null,body:null,headers:$,status:_})}).then((Z)=>K({error:null,body:Z,headers:$,status:_})).catch((Z)=>Q({error:null,body:Z,headers:$,status:_}))}catch(Z){Q({body:null,error:Z.message,headers:$,status:_})}}function l(U,z,G,H,K,Q,X,Y,$){try{let _=new WebSocket(U);return _.onopen=function(){z()},_.onclose=function(Z){G(Z)},_.onerror=function(Z){console.error(Z),Y("WebSocket error received")},_.onmessage=function(Z){if(typeof Z.data==="string")try{if($){if(H)H(Z.data);return}let B=JSON.parse(Z.data);if(K)K(B)}catch(B){if($&&H)H(Z.data);else Y(B.message)}else if(Z.data instanceof Blob){if(Q)Q(Z.data)}else if(Z.data instanceof ArrayBuffer){if(X)X(Z.data)}else console.error("Received unknown message type from WebSocket",Z),Y("Unknown message received from WebSocket")},_}catch(_){Y(_.message)}}function x(U){if(U)U.close(),U=null}function i(U,z){if(z&&U&&U.readyState===WebSocket.OPEN)U.send(z)}function d(U,z,G,H,K,Q){try{let X=new EventSource(U);return X.onopen=function(){z()},X.onerror=function(){K("EventSource error received")},X.onmessage=function(Y){try{if(Q){if(G)G(Y.data);return}let $=JSON.parse(Y.data);if(H)H($)}catch($){if(Q&&G)G(Y.data);else K($.message)}},X}catch(X){K(X.message)}}function p(U){if(U)U.close(),U=null}function a(U,z){if(!U.classList)U.classList=new Set;for(let G of z)for(let H of G.trim().split(" "))if(H)U.classList.add(H)}function s(U,z){if(!U.parent)return;z.nextSibling=U.nextSibling,z.parent=U.parent,U.parent.child=z}function r(U,z={}){let G=Object.keys(z),H=Object.values(z);return new Function(...G,U)(...H)}function c(U){if(U===null||U===void 0)return 0;if(typeof U==="number")return 1;if(typeof U==="string")return 2;if(typeof U==="boolean")return 3;if(Array.isArray(U))return 4;return 5}function o(U){return function(){U|=0,U=U+2654435769|0;var z=U^U>>>15;return z=Math.imul(z,2246822507),z=z^z>>>13,z=Math.imul(z,3266489909),((z^z>>>16)>>>0)/4294967296}}function n(){let U=new Uint32Array(1);return crypto.getRandomValues(U)[0]}function t(){return Math.random()}function W(U,z){switch(U.type){case 3:for(let G of U.children)W(G,z);break;case 0:if(U.child)W(U.child,z);break;default:z(U.domRef);break}}function q(U){switch(U.type){case 3:{if(!U.children||U.children.length===0)return null;return q(U.children[0])}case 0:if(!U.child)return null;return q(U.child);default:return U.domRef}}function N(U){switch(U.type){case 3:{if(!U.children||U.children.length===0)return null;return N(U.children[U.children.length-1])}case 0:if(!U.child)return null;return N(U.child);default:return U.domRef}}function A(U,z,G,H){if(!U&&!z)return;else if(!U)D(z,G,H);else if(!z)O(U,G,H);else if(U.type===2&&z.type===2)JU(U,z,H);else if(U.type===0&&z.type===0){if(z.key===U.key){if(z.child=U.child,z.componentId=U.componentId,U.child)U.child.parent=z;if(z.diffProps)z.diffProps();return}V(U,z,G,H)}else if(U.type===3&&z.type===3)if(z.key===U.key){let K=N(U),Q=K?K.nextSibling:H.nextSibling(U);XU(U.children,z.children,G,H,Q)}else V(U,z,G,H);else if(U.type===1&&z.type===1)if(z.tag===U.tag&&z.key===U.key)z.domRef=U.domRef,QU(U,z,H);else V(U,z,G,H);else V(U,z,G,H)}function JU(U,z,G){if(U.text!==z.text)G.setTextContent(U.domRef,z.text);z.domRef=U.domRef;return}function V(U,z,G,H){if(U.type===3){let X=N(U),Y=X?X.nextSibling:H.nextSibling(U);if(O(U,G,H),Y)C(G,2,Y,z,H);else D(z,G,H);return}switch(U.type){case 2:break;default:P(U);break}let K=q(U),Q=N(U);if(!K||!Q){let X=H.nextSibling(U);if(X)C(G,2,X,z,H);else D(z,G,H)}else if(K!==Q){let X=Q.nextSibling;if(W(U,(Y)=>H.removeChild(G,Y)),X)C(G,2,X,z,H);else D(z,G,H)}else C(G,1,K,z,H);switch(U.type){case 2:break;default:R(U);break}}function O(U,z,G){switch(U.type){case 2:break;case 3:for(let H of U.children)O(H,z,G);return;default:P(U);break}switch(W(U,(H)=>G.removeChild(z,H)),U.type){case 2:break;default:R(U);break}}function R(U){if(U.type===3){for(let z of U.children)if(z.type!==2)R(z);return}switch(AU(U),U.type){case 1:for(let z of U.children)if(z.type!==2)R(z);break;case 0:if(U.child&&U.child.type!==2)R(U.child);break}}function AU(U){if(U.type===1&&U.onDestroyed)U.onDestroyed();if(U.type===0)wU(U)}function BU(U){switch(U.type){case 0:break;case 1:if(U.onBeforeDestroyed)U.onBeforeDestroyed();break;default:break}}function P(U){if(U.type===3){for(let z of U.children)if(z.type!==2)P(z);return}switch(BU(U),U.type){case 1:for(let z of U.children){if(z.type===2)continue;P(z)}break;case 0:if(U.child&&U.child.type!==2)P(U.child);break}}function QU(U,z,G){NU(U?U.props:{},z.props,z.domRef,z.ns==="svg",G),SU(U?U.classList:null,z.classList,z.domRef,G),CU(U?U.css:{},z.css,z.domRef,G),XU(U?U.children:[],z.children,z.domRef,G),IU(z)}function SU(U,z,G,H){if(!U&&!z)return;if(!U){for(let K of z)H.addClass(K,G);return}if(!z){for(let K of U)H.removeClass(K,G);return}for(let K of U)if(!z.has(K))H.removeClass(K,G);for(let K of z)if(!U.has(K))H.addClass(K,G);return}function NU(U,z,G,H,K){var Q;for(let X in U)if(Q=z[X],Q===void 0)if(H||!(X in G)||X==="disabled")K.removeAttribute(G,X);else K.setAttribute(G,X,"");else{if(Q===U[X]&&X!=="checked"&&X!=="value")continue;if(H)if(X==="href")K.setAttributeNS(G,"http://www.w3.org/1999/xlink","href",Q);else K.setAttribute(G,X,Q);else if(X in G&&!(X==="list"||X==="form"))G[X]=Q;else K.setAttribute(G,X,Q)}for(let X in z){if(U&&X in U)continue;if(Q=z[X],H)if(X==="href")K.setAttributeNS(G,"http://www.w3.org/1999/xlink","href",Q);else K.setAttribute(G,X,Q);else if(X in G&&!(X==="list"||X==="form"))G[X]=z[X];else K.setAttribute(G,X,Q)}}function CU(U,z,G,H){H.setInlineStyle(U,z,G)}function EU(U,z){if(U.length===0||z.length===0)return!1;for(var G=0;G<U.length;G++)if(U[G].key===null||U[G].key===void 0)return!1;for(var G=0;G<z.length;G++)if(z[G].key===null||z[G].key===void 0)return!1;return!0}function XU(U,z,G,H,K=null){if(EU(U,z))PU(U,z,G,H,K);else for(let Q=0;Q<Math.max(z.length,U.length);Q++){let X=U[Q],Y=z[Q];if(!X&&Y)if(K)C(G,2,K,Y,H);else D(Y,G,H);else A(X,Y,G,H)}}function DU(U,z){if(U.ns==="svg")U.domRef=z.createElementNS("http://www.w3.org/2000/svg",U.tag);else if(U.ns==="mathml")U.domRef=z.createElementNS("http://www.w3.org/1998/Math/MathML",U.tag);else U.domRef=z.createElement(U.tag)}function YU(U,z,G){if(z.onCreated)z.onCreated(z.domRef)}function C(U,z,G,H,K){switch(H.type){case 2:switch(H.domRef=K.createTextNode(H.text),z){case 2:K.insertBefore(U,H.domRef,G);break;case 0:K.appendChild(U,H.domRef);break;case 1:K.replaceChild(U,H.domRef,G);break}break;case 3:for(let Q of H.children)C(U,2,G,Q,K);if(z===1&&G)K.removeChild(U,G);break;case 0:MU(U,z,G,H,K);break;case 1:if(H.onBeforeCreated)H.onBeforeCreated();if(DU(H,K),H.onCreated)H.onCreated(H.domRef);switch(QU(null,H,K),z){case 2:K.insertBefore(U,H.domRef,G);break;case 0:K.appendChild(U,H.domRef);break;case 1:K.replaceChild(U,H.domRef,G);break}break}}function IU(U){if(U.tag==="canvas"&&U.draw)U.draw(U.domRef)}function wU(U){U.unmount(U.componentId)}function MU(U,z,G,H,K){let Q=H.mount(U);H.componentId=Q.componentId,H.child=Q.componentTree,Q.componentTree.parent=H;let X=q(Q.componentTree);if(Q.componentTree.type!==0){if(z===1&&G)if(!X)K.removeChild(U,G);else if(Q.componentTree.type===3)W(Q.componentTree,(Y)=>K.insertBefore(U,Y,G)),K.removeChild(U,G);else K.replaceChild(U,X,G);else if(z===2)if(G)W(Q.componentTree,(Y)=>K.insertBefore(U,Y,G));else W(Q.componentTree,(Y)=>K.appendChild(U,Y))}}function D(U,z,G){C(z,0,null,U,G)}function KU(U,z,G,H){let K=G?q(G)??H.nextSibling(G):null;if(K)W(z,(Q)=>H.insertBefore(U,Q,K));else W(z,(Q)=>H.appendChild(U,Q))}function RU(U,z,G,H){let K=q(U),Q=q(z);if(K&&Q&&(U.type===1||U.type===2)&&(z.type===1||z.type===2)){H.swapDOMRefs(K,Q,G);return}let X=N(U),Y=X?X.nextSibling:H.nextSibling(U),$=q(z)??H.nextSibling(z);if($)W(U,(_)=>H.insertBefore(G,_,$));else W(U,(_)=>H.appendChild(G,_));if(Y)W(z,(_)=>H.insertBefore(G,_,Y));else W(z,(_)=>H.appendChild(G,_))}function PU(U,z,G,H,K=null){var Q=0,X=0,Y=U.length-1,$=z.length-1,_,Z,B,S,J,f,HU;for(;;){if(X>$&&Q>Y)break;if(Z=z[X],B=z[$],J=U[Q],S=U[Y],Q>Y){let M=(J?q(J)??H.nextSibling(J):null)??K;if(M)C(G,2,M,Z,H);else D(Z,G,H);U.splice(X,0,Z),X++}else if(X>$){_=Y;while(Y>=Q)O(U[Y--],G,H);U.splice(Q,_-Q+1);break}else if(J.key===Z.key)A(U[Q++],z[X++],G,H);else if(S.key===B.key)A(U[Y--],z[$--],G,H);else if(J.key===B.key&&Z.key===S.key)RU(S,J,G,H),FU(U,Q,Y),A(U[Q++],z[X++],G,H),A(U[Y--],z[$--],G,H);else if(J.key===B.key){let I=N(S),M=I?I.nextSibling:H.nextSibling(S);if(M)W(J,(T)=>H.insertBefore(G,T,M));else W(J,(T)=>H.appendChild(G,T));U.splice(Y,0,U.splice(Q,1)[0]),A(U[Y--],z[$--],G,H)}else if(S.key===Z.key)KU(G,S,J,H),U.splice(Q,0,U.splice(Y,1)[0]),A(U[Q++],Z,G,H),X++;else{f=!1,_=Q;while(_<=Y){if(U[_].key===Z.key){f=!0,HU=U[_];break}_++}if(f)U.splice(Q,0,U.splice(_,1)[0]),A(U[Q++],Z,G,H),KU(G,HU,U[Q],H),X++;else{let I=q(J)??H.nextSibling(J);if(I)C(G,2,I,Z,H);else D(Z,G,H);U.splice(Q++,0,Z),X++,Y++}}}}function FU(U,z,G){let H=U[z];U[z]=U[G],U[G]=H}function e(U,z,G,H,K){for(let Q of z)K.addEventListener(U,Q.name,function(X){LU(X,U,G,H,K)},Q.capture)}function LU(U,z,G,H,K){G(function(Q){if(Array.isArray(U))for(let X of U)ZU(X,Q,z,H,K);else ZU(U,Q,z,H,K)})}function ZU(U,z,G,H,K){var Q=K.getTarget(U);if(Q){let X=VU(G,Q,K);E(U,z,X,H,K)}}function VU(U,z,G){var H=[];while(!G.isEqual(U,z))if(H.unshift(z),z&&G.parentNode(z))z=G.parentNode(z);else return H;return H}function E(U,z,G,H,K){if(!G.length){if(H)console.warn('Event "'+U.type+'" did not find an event handler to dispatch on',z,U);return}else if(G.length>1){if(z.type===2)return;else if(z.type===3){for(let Q of z.children)if(F(Q,G[0],K)){E(U,Q,G,H,K);return}return}else if(z.type===0){if(!z.child){if(H)throw console.error("VComp has no child property set during event delegation",z),console.error("This means the Component has not been fully mounted, this should never happen"),new Error("VComp has no .child property set during event delegation");return}return E(U,z.child,G,H,K)}else if(z.type===1){if(K.isEqual(z.domRef,G[0])){let Q=z.events.captures[U.type];if(Q){let X=Q.options;if(X.preventDefault)U.preventDefault();if(!U.captureStopped)Q.runEvent(U,z.domRef);if(X.stopPropagation)U.captureStopped=!0}G.splice(0,1);for(let X of z.children)if(F(X,G[0],K)){E(U,X,G,H,K);return}}return}}else if(z.type===0){if(z.child)E(U,z.child,G,H,K)}else if(z.type===3){for(let Q of z.children)if(F(Q,G[0],K)){E(U,Q,G,H,K);return}}else if(z.type===1){let Q=z.events.captures[U.type];if(Q&&!U.captureStopped){let Y=Q.options;if(K.isEqual(G[0],z.domRef)){if(Y.preventDefault)U.preventDefault();if(Q.runEvent(U,G[0]),Y.stopPropagation)U.captureStopped=!0}}let X=z.events.bubbles[U.type];if(X&&!U.captureStopped){let Y=X.options;if(K.isEqual(G[0],z.domRef)){if(Y.preventDefault)U.preventDefault();if(X.runEvent(U,G[0]),!Y.stopPropagation)$U(z.parent,U)}}else if(!U.captureStopped)$U(z.parent,U)}}function $U(U,z){while(U)switch(U.type){case 2:break;case 3:U=U.parent;break;case 1:let G=U.events.bubbles[z.type];if(G){let H=G.options;if(H.preventDefault)z.preventDefault();if(G.runEvent(z,U.domRef),H.stopPropagation)return}U=U.parent;break;case 0:if(!U.eventPropagation)return;U=U.parent;break}}function L(U,z){if(typeof U[0]==="object"){var G=[];for(var H=0;H<U.length;H++)G.push(L(U[H],z));return G}for(let Y of U)z=z[Y];var K;if(z instanceof Array||"length"in z&&z.localName!=="select"){K=[];for(var Q=0;Q<z.length;Q++)K.push(L([],z[Q]));return K}K={};for(var X in OU(z)){if(z.localName==="input"&&(X==="selectionDirection"||X==="selectionStart"||X==="selectionEnd"))continue;if(typeof z[X]=="string"||typeof z[X]=="number"||typeof z[X]=="boolean")K[X]=z[X]}return K}function F(U,z,G){switch(U.type){case 3:for(let H of U.children)if(F(H,z,G))return!0;return!1;case 0:return U.child?F(U.child,z,G):!1;default:return G.isEqual(U.domRef,z)}}function OU(U){var z={},G=0;do{var H=Object.getOwnPropertyNames(U);for(G=0;G<H.length;G++)z[H[G]]=null}while(U=Object.getPrototypeOf(U));return z}var j={addEventListener:(U,z,G,H)=>{U.addEventListener(z,G,H)},delegator:(U,z,G,H,K)=>{e(U,z,G,H,K)},isEqual:(U,z)=>{return U===z},getTarget:(U)=>{return U.target},parentNode:(U)=>{return U.parentNode}},_U={getInlineStyle:(U,z)=>{return U.style[z]},firstChild:(U)=>{return U.firstChild},lastChild:(U)=>{return U.lastChild},getAttribute:(U,z)=>{if(z==="class")return U.className;if(z in U)return U[z];return U.getAttribute(z)},getTag:(U)=>{return U.nodeName},getTextContent:(U)=>{return U.textContent},children:(U)=>{return U.childNodes}},WU={mountComponent:function(U,z){return},unmountComponent:function(U){return},modelHydration:function(U,z){return}},UU={nextSibling:(U)=>{let z=U.nextSibling;while(z)switch(z.type){case 0:case 3:{let G=q(z);if(G)return G;z=z.nextSibling;break}default:return z.domRef}return null},createTextNode:(U)=>{return document.createTextNode(U)},createElementNS:(U,z)=>{return document.createElementNS(U,z)},appendChild:(U,z)=>{return U.appendChild(z)},replaceChild:(U,z,G)=>{return U.replaceChild(z,G)},removeChild:(U,z)=>{return U.removeChild(z)},createElement:(U)=>{return document.createElement(U)},addClass:(U,z)=>{if(U)z.classList.add(U)},removeClass:(U,z)=>{if(U)z.classList.remove(U)},insertBefore:(U,z,G)=>{return U.insertBefore(z,G)},swapDOMRefs:(U,z,G)=>{let H=U.nextSibling;G.insertBefore(U,z),G.insertBefore(z,H);return},setInlineStyle:(U,z,G)=>{var H;for(let K in U)if(H=z[K],!H)if(K in G.style)G.style[K]="";else G.style.setProperty(K,"");else if(H!==U[K])if(K in G.style)G.style[K]=H;else G.style.setProperty(K,H);for(let K in z){if(U&&U[K])continue;if(K in G.style)G.style[K]=z[K];else G.style.setProperty(K,z[K])}return},setAttribute:(U,z,G)=>{return U.setAttribute(z,G)},setAttributeNS:(U,z,G,H)=>{return U.setAttributeNS(z,G,H)},removeAttribute:(U,z)=>{return U.removeAttribute(z)},setTextContent:(U,z)=>{U.textContent=z;return},flush:()=>{return},getHead:function(){return document.head},getRoot:function(){return document.body}};function zU(U){var z=0,G=U.length>0?[U[0]]:[];for(var H=1;H<U.length;H++){if(G[z].type===2&&U[H].type===2){G[z].text+=U[H].text;continue}G[++z]=U[H]}for(let K of G)if(K.type===3)K.children=zU(K.children);return G}function GU(U,z,G,H,K){if(!G||!z)return!1;if(z.nodeType===3)return!1;if(!b(U,G,H.firstChild(z),H,K)){if(U)console.warn("[DEBUG_HYDRATE] Could not copy DOM into virtual DOM, falling back to diff");while(H.firstChild(z))K.removeChild(z,H.lastChild(z));return!1}else if(U)console.info("[DEBUG_HYDRATE] Successfully prerendered page");return!0}function k(U,z,G){if(U)console.warn("[DEBUG_HYDRATE] VTree differed from node",z,G)}function qU(U,z){let G=N(U);return G?G.nextSibling:z}function b(U,z,G,H,K){switch(z.type){case 0:let X=z.mount(G.parentNode);if(z.componentId=X.componentId,z.child=X.componentTree,X.componentTree.parent=z,!b(U,z.child,G,H,K))return!1;break;case 3:z.children=zU(z.children);for(let $ of z.children){if(!G)return k(U,$,null),!1;if(!b(U,$,G,H,K))return!1;G=qU($,G)}break;case 2:if(G.nodeType!==3||z.text.trim()!==G.textContent.trim())return k(U,z,G),!1;z.domRef=G;break;case 1:if(G.nodeType!==1)return k(U,z,G),!1;z.domRef=G,z.children=zU(z.children),YU(G,z,K);let Y=G.firstChild;for(var Q=0;Q<z.children.length;Q++){let $=z.children[Q];if(!Y)return k(U,$,null),!1;if(!b(U,$,Y,H,K))return!1;Y=qU($,Y)}break}return!0}globalThis.miso={hydrationContext:_U,eventContext:j,drawingContext:UU,componentContext:WU,diff:A,hydrate:GU,version:m,callBlur:h,callFocus:y,callSelect:u,callSetSelectionRange:g,eventJSON:L,fetchCore:v,eventSourceConnect:d,eventSourceClose:p,websocketConnect:l,websocketClose:x,websocketSend:i,updateRef:s,inline:r,typeOf:c,mathRandom:t,getRandomValues:n,splitmix32:o,populateClass:a,delegateEvent:E,delegator:j.delegator,setDrawingContext:function(U){let z=globalThis[U].drawingContext,G=globalThis[U].eventContext,H=globalThis[U].componentContext;if(!z)console.error('Custom rendering engine ("drawingContext") is not defined at globalThis[name].drawingContext',U);if(!G)console.error('Custom event delegation ("eventContext") is not defined at globalThis[name].eventContext',U);if(!H)console.error('Custom component context ("componentContext") is not defined at globalThis[name].componentContext',U);globalThis.miso.drawingContext=z,globalThis.miso.eventContext=G,globalThis.miso.componentContext=H}};
miso.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.2 name:                miso-version:             1.10.0.0+version:             1.11.0.0 category:            Web, Miso, Data Structures license:             BSD-3-Clause license-file:        LICENSE
src/Miso.hs view
@@ -73,7 +73,7 @@ --   This is the templating function that is used to construct a new virtual DOM --   (or HTML if rendering on the server). ----- * __update__: @'update' :: action -> 'Effect' parent model action@+-- * __update__: @'update' :: action -> 'Effect' parent props model action@ --   The 'update' function handles how the 'model' evolves over time in response --   to events that are raised by the application. This function takes any @action@, --   updating the @model@ and optionally introduces 'IO' into the system.@@ -97,8 +97,8 @@ -- -- @ -- data 'SomeComponent' parent---   = forall model action . Eq model---   => 'SomeComponent' ('Component' parent model action)+--   = forall model action props . (Eq model, Eq props)+--   => 'SomeComponent' props ('Component' parent model action) -- @ -- -- The smart constructors:@@ -127,22 +127,23 @@ -- import qualified Miso.Html.Property as HP -- ----------------------------------------------------------------------------- --                        * - The type of the parent Component 'model'---                        |     * - The type of the current Component's 'model'---                        |     |    * - The type of the action that updates the 'model'---                        |     |    |--- counter :: 'Component' parent Int Action+--                        |    * - The type of the parent Component 'props' accessible to the child+--                        |    |     * - The type of the current Component's 'model'+--                        |    |     |   * - The type of the action that updates the 'model'+--                        |    |     |   |+-- counter :: 'Component' ROOT () Int Action -- counter = 'vcomp' m u v --   where --     m :: Int --     m = 0 -----     u :: Action -> 'Effect' parent Int Action+--     u :: Action -> 'Effect' ROOT () Int Action --     u = \\case --       Add -> 'this' += 1 --       Subtract -> 'this' -= 1 -----     v :: Int -> 'View' Int Action---     v x = 'vfrag'+--     v :: () -> Int -> 'View' Int Action+--     v _ x = 'vfrag' --       [ H.button_ [ HE.onClick Add, HP.id_ "add" ] [ "+" ] --       , text (ms x) --       , H.button_ [ HE.onClick Subtract, HP.id_ "subtract" ] [ "-" ]@@ -203,7 +204,7 @@ -- ('+>') --   :: forall child model action a . Eq child --   => 'MisoString'---   -> 'Component' model child action+--   -> 'Component' model () child action --   -> 'View' model a -- key '+>' vcomp = 'VComp' (Just (toKey key)) ('SomeComponent' vcomp) -- @@@ -211,7 +212,7 @@ -- Practically, using this combinator looks like: -- -- @--- view :: Int -> 'View' Int action+-- view :: () -> Int -> 'View' Int action -- view x = 'div_' [ 'id_' "container" ] [ "counter" '+>' counter ] -- @ --@@ -233,7 +234,7 @@ -- The 'App' type signature is a synonym for 'Component' 'ROOT' -- -- @--- type 'App' model action = 'Component' 'ROOT' model action+-- type 'App' model action = 'Component' 'ROOT' () model action -- @ -- -- 'ROOT' is a type tag that encodes a 'Component' as top-level. Which means it has no @parent@, hence we mark @parent@ as 'ROOT'.@@ -244,6 +245,149 @@ -- -- 'startApp' and 'miso' will always infer @parent@ as 'ROOT'. --+-- = Props+--+-- Inspired by [React props](https://react.dev/learn/passing-props-to-a-component),+-- @miso@ allows a parent 'Component' to pass read-only data down to a child 'Component'+-- via a mechanism called /props/ (short for /properties/).+--+-- == Props vs. Component-local state+--+-- * __model__: Component-local state. It is owned and mutated exclusively by the 'Component'+--   itself through its 'Miso.Types.update' function. No other 'Component' can write to it directly.+--+-- * __props__: Data /inherited/ from the @parent@ 'Component'. Props flow downward through+--   the component hierarchy and are read-only from the child's perspective. The parent decides+--   what props to pass at mount time; the child cannot mutate them. Props that change in a+--   the parent cause the child to re-render.+--+-- This mirrors the distinction in React between component state (@useState@) and props+-- received from above (@function MyComponent({ name }) { ... }@).+--+-- === When to use props+--+-- Props are best suited for /metadata/ — contextual or configuration data that the child needs+-- to know about but should not own. Good examples: a user's display name, a theme token, a+-- locale string, or a read-only identifier used to customise rendering.+--+-- If the data drives the child's own business logic — counters it increments, form fields it+-- edits, async state it manages — that data belongs in the child's @model@ instead. Putting+-- mutable business-logic state in @props@ would require the parent to own and thread through+-- every change, creating unnecessary coupling. Prefer @props@ for \"what the child should+-- know\" and @model@ for \"what the child should do\".+--+-- == Props in 'Miso.Types.view'+--+-- The 'Miso.Types.view' field of a 'Component' always takes @props@ as its first argument:+--+-- @+-- view :: props -> model -> 'View' model action+-- @+--+-- Top-level applications have no parent, so @props@ is always @()@:+--+-- @+-- view :: () -> model -> 'View' model action+-- view _props model = …+-- @+--+-- == Props in 'Effect' \/ 'Miso.Types.update'+--+-- Use 'getProps' inside the 'Effect' monad to read the current value of @props@:+--+-- @+-- update :: Action -> 'Effect' parent props Model Action+-- update = \\case+--   SomeAction -> do+--     p <- 'getProps'+--     'io_' ('consoleLog' (ms (show p)))+-- @+--+-- Alternatively, use the 'Miso.Lens.view' combinator with the 'props' lens:+--+-- @+-- update = \\case+--   SomeAction -> do+--     p <- 'Miso.Lens.view' 'props'+--     …+-- @+--+-- == 'ROOT' — the top-level 'Component'+--+-- When a 'Component' is passed to 'startApp' (or 'miso') it has no parent.+-- The @parent@ type is specialized to 'ROOT' and @props@ is fixed to @()@:+--+-- @+-- type 'App' model action = 'Component' 'ROOT' () model action+-- @+--+-- Because there is no parent to inherit from, @props@ will always be @()@ for a+-- root-level 'Component'. You can simply ignore the first argument in 'view' and+-- skip 'getProps' in 'Miso.Types.update'.+--+-- == Passing props to a child 'Component'+--+-- Use 'mountWithProps_' (keyed) or 'mountWithProps' (unkeyed) in the parent's 'view' to+-- mount a child and supply its props:+--+-- @+-- 'mountWithProps_'+--   :: ('Eq' child, 'Eq' props)+--   => 'MisoString'+--   -> props+--   -> 'Component' parent props child action+--   -> 'View' parent a+-- @+--+-- == Example: child reading parent-supplied props+--+-- The following shows a parent 'Component' that maintains a greeting string in its+-- @model@ and passes it as @props@ to a child 'Component'. The child renders the+-- greeting and can also read it from within its 'Miso.Types.update' function.+--+-- @+-- -----------------------------------------------------------------------------+-- -- The props type: what the parent shares with the child+-- newtype Greeting = Greeting 'MisoString' deriving ('Eq')+-- -----------------------------------------------------------------------------+-- -- Child component+-- --+-- --                   parent      props    model  action+-- --                   |           |        |      |+-- child :: 'Component' ParentModel Greeting ()     ChildAction+-- child = 'vcomp' () updateChild viewChild+--   where+--     viewChild :: Greeting -> () -> 'View' () ChildAction+--     viewChild (Greeting g) _ =+--       'div_' [] [ 'text' ("Hello, " <> g <> "!") ]+--+--     updateChild :: ChildAction -> 'Effect' ParentModel Greeting () ChildAction+--     updateChild = \\case+--       ReadGreeting -> do+--         Greeting g <- 'getProps'+--         'io_' ('consoleLog' g)+-- -----------------------------------------------------------------------------+-- -- Parent component: owns the greeting, passes it to the child as props+-- parent :: 'App' ParentModel ParentAction+-- parent = 'vcomp' (ParentModel "World") 'noop' viewParent+--   where+--     viewParent :: () -> ParentModel -> 'View' ParentModel ParentAction+--     viewParent _ (ParentModel g) =+--       'mountWithProps_' "child" (Greeting g) child+-- -----------------------------------------------------------------------------+-- newtype ParentModel = ParentModel 'MisoString' deriving ('Eq')+-- data ChildAction = ReadGreeting+-- data ParentAction+-- @+--+-- A few things to notice:+--+-- * The child's @parent@ type parameter is @ParentModel@. This must match the+--   parent 'Component' @model@ type — 'mountWithProps_' enforces this at compile time.+-- * 'getProps' inside the child's 'Miso.Types.update' yields a @Greeting@, not+--   the full @ParentModel@. The child only sees what the parent explicitly chose to share.+-- * The root 'App' always has @props ~ ()@; no extra plumbing is needed when calling 'startApp'.+-- -- = 'VComp' lifecycle hooks -- -- 'Component' are mounted on the fly during diffing. All t'Component` are equipped with `mount` and `unmount` hooks. This allows the defining of custom actions that will be processed in response to lifecycle events.@@ -271,7 +415,7 @@ -- -- data Action = Highlight DOMRef ----- update :: Action -> 'Effect' parent model Action+-- update :: Action -> 'Effect' parent props model Action -- update = \\case --   Highlight domRef -> 'io_' $ do --     ['js'| hljs.highlight(${domRef}) |]@@ -344,7 +488,7 @@ --   , 'li_' [ 'key_' "key-2" ] [ "b" ] --   , "key-3" '+>' counter --   , 'textKey' "key-4" "text here"---   , vfrag_ "key-5" [ "foo", "bar" ]+--   , 'vfrag_' "key-5" [ "foo", "bar" ] --   ] -- @ --@@ -420,7 +564,7 @@ -- The 'Effect' type is defined as a 'RWS'. -- -- @--- type 'Effect' parent model action = 'RWS' ('ComponentInfo' parent) ['Schedule' action] model ()+-- type 'Effect' parent props model action = 'RWS' ('ComponentInfo' parent props) ['Schedule' action] model () -- @ -- -- * The 'Control.Monad.Reader' portion of 'Effect' is 'ComponentInfo'. 'ask', 'asks', 'Miso.Lens.view' can be used to access its fields.@@ -470,6 +614,8 @@ -- * 'broadcast' -- * 'mail' -- * 'mailParent'+-- * 'mailChildren'+-- * 'mailAncestors' -- -- All t'Component' have a 'mailbox' that can receive messages (as t'Miso.JSON.Value') from other t'Component'. -- This is meant to be used with the 'checkMail' function. The 'mail' function allows a 'Component' to send a specific message (as 'Value') to another t'Component' via its t'ComponentId'.@@ -585,7 +731,7 @@ -- -- import Miso.FFI.QQ ('js') ----- update :: Action -> 'Effect' parent model Action+-- update :: Action -> 'Effect' parent props model Action -- update = \\case --   Log msg -> io_ [js| console.log(${msg}) |] --@@ -667,7 +813,7 @@ -- A simple example of static prerendering would be an @index.html@ page with some HTML -- -- @--- echo "\<html\>\<head\>\<\/head\>\<body\>hello world\<\/body\>" > index.html+-- echo "\<html\>\<head\>\<\/head\>\<body\>hello world\<\/body\>\<html\>" > index.html -- @ -- -- And a miso application that looks like:@@ -720,6 +866,7 @@   , parent   , mailParent   , mailChildren+  , mailAncestors   , broadcast     -- ** Subscriptions   , startSub
src/Miso/Effect.hs view
@@ -1,5 +1,6 @@ ----------------------------------------------------------------------------- {-# LANGUAGE CPP                        #-}+{-# LANGUAGE FlexibleContexts           #-} {-# LANGUAGE FlexibleInstances          #-} ----------------------------------------------------------------------------- {-# OPTIONS_GHC -fno-warn-orphans       #-}@@ -52,14 +53,18 @@   , componentInfoId   -- *** Internal   , runEffect+  -- *** Props+  , componentInfoProps+  , props+  , getProps   ) where ----------------------------------------------------------------------------- import           Control.Monad (void) import           Data.Foldable (for_)-import           Control.Monad.RWS (RWS, put, tell, execRWS, censor)+import           Control.Monad.RWS (RWS, put, tell, execRWS, censor, MonadReader) ------------------------------------------------------------------------------import           Miso.Lens import           Miso.DSL.FFI+import           Miso.Lens ----------------------------------------------------------------------------- -- | Smart constructor for t'ComponentInfo' mkComponentInfo@@ -69,18 +74,20 @@   -- ^ @parent@ 'ComponentId'   -> DOMRef   -- ^ 'DOMRef'-  -> ComponentInfo parent+  -> props+  -> ComponentInfo parent props mkComponentInfo = ComponentInfo ----------------------------------------------------------------------------- -- | This is the 'Reader r' in t'Miso.Effect'. Accessible via 'Control.Monad.Reader.ask'. It holds -- a phantom type for @parent@. This is used as a witness when calling the -- 'parent' function. It gives access to 'Component' metadata such as the 'DOMRef' the -- 'Component' was mounted on and the 'ComponentId' associated with it.-data ComponentInfo parent+data ComponentInfo parent props   = ComponentInfo   { _componentInfoId :: ComponentId   , _componentInfoParentId :: ComponentId   , _componentInfoDOMRef :: DOMRef+  , _componentInfoProps :: props   } ----------------------------------------------------------------------------- -- | Lens for accessing the t'ComponentId' from t'ComponentInfo'.@@ -93,7 +100,7 @@ -- @ -- -- @since 1.9.0.0-componentInfoId :: Lens (ComponentInfo parent) ComponentId+componentInfoId :: Lens (ComponentInfo parent props) ComponentId componentInfoId = lens _componentInfoId $ \r x -> r { _componentInfoId = x } ----------------------------------------------------------------------------- -- | Lens for accessing the parents's  t'ComponentId' from t'ComponentInfo'.@@ -107,7 +114,7 @@ -- @ -- -- @since 1.9.0.0-componentInfoParentId :: Lens (ComponentInfo parent) ComponentId+componentInfoParentId :: Lens (ComponentInfo parent props) ComponentId componentInfoParentId = lens _componentInfoParentId $ \r x -> r { _componentInfoParentId = x } ----------------------------------------------------------------------------- -- | Lens for accessing the underlying t'Miso.Types.Component' t'DOMRef'.@@ -120,9 +127,48 @@ -- @ -- -- @since 1.9.0.0-componentInfoDOMRef :: Lens (ComponentInfo parent) DOMRef+componentInfoDOMRef :: Lens (ComponentInfo parent props) DOMRef componentInfoDOMRef = lens _componentInfoDOMRef $ \r x -> r { _componentInfoDOMRef = x } -----------------------------------------------------------------------------+-- | Lens for accessing the underlying t'Miso.Types.Component' @props@.+--+-- @+--   update = \case+--     SomeAction -> do+--       props <- view componentInfoProps+--       someAction props+-- @+--+-- @since 1.9.0.0+componentInfoProps :: Lens (ComponentInfo parent props) props+componentInfoProps = lens _componentInfoProps $ \r x -> r { _componentInfoProps = x }+-----------------------------------------------------------------------------+-- | Lens for accessing the underlying t'Miso.Types.Component' @props@.+--+-- This is a shorter convenience lens that is a synonynm for 'componentInfoProps'.+-- See 'getProps' for usage in the 'Effect' monad.+--+-- @+--   update = \case+--     SomeAction ->+--       someAction =<< view props+-- @+--+props :: Lens (ComponentInfo parent props) props+props = componentInfoProps+-----------------------------------------------------------------------------+-- | @props@ retrieval from within the 'Effect' monad.+--+-- @+--   update = \case+--     SomeAction -> do+--       props <- getProps+--       someAction props+-- @+--+getProps :: MonadReader (ComponentInfo parent props) m => m props+getProps = Miso.Lens.view props+----------------------------------------------------------------------------- -- | 'ComponentId' of the current t'Miso.Types.Component' type ComponentId = Int -----------------------------------------------------------------------------@@ -138,7 +184,7 @@ ----------------------------------------------------------------------------- -- | Smart constructor for an 'Effect' with exactly one action. infixl 0 <#-(<#) :: model -> IO action -> Effect parent model action+(<#) :: model -> IO action -> Effect parent props model action (<#) m action = put m >> tell [ async $ \f -> f =<< action ] ----------------------------------------------------------------------------- async :: (Sink action -> IO ()) -> Schedule action@@ -146,7 +192,7 @@ ----------------------------------------------------------------------------- -- | `Effect` smart constructor, flipped infixr 0 #>-(#>) :: IO action -> model -> Effect parent model action+(#>) :: IO action -> model -> Effect parent props model action (#>) = flip (<#) ----------------------------------------------------------------------------- -- | Smart constructor for an 'Effect' with multiple 'IO' actions.@@ -155,7 +201,7 @@ batch   :: [IO action]   -- ^ Batch of 'IO' actions to execute-  -> Effect parent model action+  -> Effect parent props model action batch actions = sequence_   [ tell [ async $ \f -> f =<< action ]   | action <- actions@@ -164,7 +210,7 @@ -- | Like @batch@ but actions are discarded -- -- @since 1.9.0.0-batch_ :: [IO ()] -> Effect parent model action+batch_ :: [IO ()] -> Effect parent props model action batch_ actions = sequence_   [ tell [ async (const action) ]   | action <- actions@@ -202,7 +248,7 @@ --   , ... --   } -- @-type Effect parent model action = RWS (ComponentInfo parent) [Schedule action] model ()+type Effect parent props model action = RWS (ComponentInfo parent props) [Schedule action] model () ----------------------------------------------------------------------------- -- | Represents a scheduled 'Effect' that is executed either synchronously -- or asynchronously.@@ -222,8 +268,8 @@ ----------------------------------------------------------------------------- -- | Internal function used to unwrap an @Effect@ runEffect-    :: Effect parent model action-    -> ComponentInfo parent+    :: Effect parent props model action+    -> ComponentInfo parent props     -> model     -> (model, [Schedule action]) runEffect = execRWS@@ -242,7 +288,7 @@ sync   :: IO action   -- ^ 'IO' action to execute synchronously-  -> Effect parent model action+  -> Effect parent props model action sync action = tell [ Schedule Sync $ \f -> f =<< action ] ----------------------------------------------------------------------------- -- | Like 'sync', except discards the result.@@ -251,7 +297,7 @@ sync_   :: IO ()   -- ^ 'IO' action to execute synchronously-  -> Effect parent model action+  -> Effect parent props model action sync_ action = tell [ Schedule Sync $ \_ -> action ] ----------------------------------------------------------------------------- -- | Schedule a single 'IO' action for later execution.@@ -263,7 +309,7 @@ io   :: IO action   -- ^ 'IO' action to execute asynchronously-  -> Effect parent model action+  -> Effect parent props model action io action = withSink (action >>=) ----------------------------------------------------------------------------- -- | Like 'io' but doesn't cause an action to be dispatched to@@ -278,7 +324,7 @@ io_   :: IO ()   -- ^ 'IO' action to execute asynchronously-  -> Effect parent model action+  -> Effect parent props model action io_ action = withSink (\_ -> void action) ----------------------------------------------------------------------------- -- | Like 'io' but generalized to any instance of 'Foldable'@@ -290,7 +336,7 @@   :: Foldable f   => IO (f action)   -- ^ @actions@ executed in batch.-  -> Effect parent model action+  -> Effect parent props model action for actions = withSink $ \sink -> actions >>= flip for_ sink ----------------------------------------------------------------------------- -- | Performs the given 'IO' action before all IO actions collected by the given@@ -302,7 +348,7 @@ -- @ -- -- @since 1.9.0.0-beforeAll :: IO () -> Effect parent model action -> Effect parent model action+beforeAll :: IO () -> Effect parent props model action -> Effect parent props model action beforeAll = modifyAllIO . (*>) ----------------------------------------------------------------------------- -- | Performs the given 'IO' action after all IO actions collected by the given@@ -312,7 +358,7 @@ -- -- > -- log that running the a websocket Effect completed -- > afterAll (consoleLog "Done running websocket effect") $ websocketConnectJSON OnConnect OnClose OnOpen OnError-afterAll :: IO () -> Effect parent model action -> Effect parent model action+afterAll :: IO () -> Effect parent props model action -> Effect parent props model action afterAll = modifyAllIO . (<*) ----------------------------------------------------------------------------- -- | Modifies all 'IO' collected by the given Effect.@@ -324,8 +370,8 @@ -- expressions in an 'Effect'. For examples see 'beforeAll' and 'afterAll'. modifyAllIO   :: (IO () -> IO ())-  -> Effect parent model action-  -> Effect parent model action+  -> Effect parent props model action+  -> Effect parent props model action modifyAllIO f = censor $ \actions ->   [ Schedule x (f <$> action)   | Schedule x action <- actions@@ -339,14 +385,14 @@ -- to turn events into actions. -- -- @--- 'update' FetchJSON = 'withSink' $ \sink -> getJSON (sink . ReceivedJSON) (sink . HandleError)+-- 'update' FetchJSON = 'withSink' $ \\sink -> getJSON (sink . ReceivedJSON) (sink . HandleError) -- @ -- -- @since 1.9.0.0 withSink   :: (Sink action -> IO ())   -- ^ Callback function that provides access to the underlying 'Sink'.-  -> Effect parent model action+  -> Effect parent props model action withSink f = tell [ async f ] ----------------------------------------------------------------------------- -- | Issue a new @action@ to be processed by 'Miso.Types.update'.@@ -364,14 +410,14 @@ issue   :: action   -- ^ @action@ to raise-  -> Effect parent model action+  -> Effect parent props model action issue action = tell [ async $ \f -> f action ] ----------------------------------------------------------------------------- -- | Helper for t'Miso.Types.Component' construction, when you want to ignore the 'Miso.Types.update' -- function temporarily, or permanently. -- -- @since 1.9.0.0-noop :: action -> Effect parent model action+noop :: action -> Effect parent props model action noop = const (pure ()) ----------------------------------------------------------------------------- -- | Type to indicate if effects should be handled asynchronously
src/Miso/EventSource.hs view
@@ -42,7 +42,7 @@   -- ^ onMessage   -> (MisoString -> action)   -- ^ onError-  -> Effect parent model action+  -> Effect parent props model action connectText = eventSourceConnectText ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/EventSource>@@ -55,12 +55,12 @@   -- ^ onMessage   -> (MisoString -> action)   -- ^ onError-  -> Effect parent model action+  -> Effect parent props model action connectJSON = eventSourceConnectJSON ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/EventSource/close> close   :: EventSource-  -> Effect parent model action+  -> Effect parent props model action close = eventSourceClose -----------------------------------------------------------------------------
src/Miso/Fetch.hs view
@@ -100,7 +100,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action getJSON url headers_ successful errorful =   withSink $ \sink ->     FFI.fetch url "GET" Nothing jsonHeaders@@ -141,7 +141,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action postJSON url body_ headers_ successful errorful =   withSink $ \sink -> do     bodyVal <- toJSVal (encode body_)@@ -165,7 +165,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action postJSON' url body_ headers_ successful errorful =   withSink $ \sink -> do     bodyVal <- toJSVal (encode body_)@@ -207,7 +207,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action putJSON url body_ headers_ successful errorful =   withSink $ \sink -> do     bodyVal <- toJSVal (encode body_)@@ -229,7 +229,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action getText url headers_ successful errorful =   withSink $ \sink ->     FFI.fetch url "GET" Nothing textHeaders_@@ -252,7 +252,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action postText url body_ headers_ successful errorful =   withSink $ \sink -> do     bodyVal <- toJSVal (encode body_)@@ -276,7 +276,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action putText url imageBody headers_ successful errorful =   withSink $ \sink -> do     body_ <- toJSVal imageBody@@ -298,7 +298,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action getBlob url headers_ successful errorful =   withSink $ \sink ->     FFI.fetch url "GET" Nothing blobHeaders_@@ -321,7 +321,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action postBlob url body_ headers_ successful errorful =   withSink $ \sink -> do     bodyVal <- toJSVal body_@@ -345,7 +345,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action putBlob url imageBody headers_ successful errorful =   withSink $ \sink -> do     body_ <- toJSVal imageBody@@ -367,7 +367,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action getFormData url headers_ successful errorful =   withSink $ \sink ->     FFI.fetch url "GET" Nothing formDataHeaders_@@ -390,7 +390,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action  postFormData url body_ headers_ successful errorful =   withSink $ \sink -> do     bodyVal <- toJSVal body_@@ -414,7 +414,7 @@   -- ^ successful callback   -> (Response error  -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action putFormData url imageBody headers_ successful errorful =   withSink $ \sink -> do     body_ <- toJSVal imageBody@@ -436,7 +436,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action getArrayBuffer url headers_ successful errorful =   withSink $ \sink ->     FFI.fetch url "GET" Nothing arrayBufferHeaders_@@ -459,7 +459,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action postArrayBuffer url body_ headers_ successful errorful =   withSink $ \sink -> do     bodyVal <- toJSVal body_@@ -483,7 +483,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action putArrayBuffer url arrayBuffer_ headers_ successful errorful =   withSink $ \sink -> do     body_ <- toJSVal arrayBuffer_@@ -505,7 +505,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action getUint8Array url headers_ successful errorful =   withSink $ \sink ->     FFI.fetch url "GET" Nothing uint8ArrayHeaders_@@ -528,7 +528,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action postUint8Array url body_ headers_ successful errorful =   withSink $ \sink -> do     bodyVal <- toJSVal body_@@ -552,7 +552,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action putUint8Array url uint8Array_ headers_ successful errorful =   withSink $ \sink -> do     body_ <- toJSVal uint8Array_@@ -576,7 +576,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action postImage url body_ headers_ successful errorful =   withSink $ \sink -> do     bodyVal <- toJSVal body_@@ -598,7 +598,7 @@   -- ^ successful callback   -> (Response error -> action)   -- ^ errorful callback-  -> Effect parent model action+  -> Effect parent props model action putImage url imageBody headers_ successful errorful =   withSink $ \sink -> do     body_ <- toJSVal imageBody
src/Miso/Html/Render.hs view
@@ -97,7 +97,7 @@   , "truespeed"   ] -----------------------------------------------------------------------------renderBuilder :: Miso.Types.View m a -> Builder+renderBuilder :: forall m a . Miso.Types.View m a -> Builder renderBuilder (VText _ "")    = fromMisoString " " renderBuilder (VText _ s)     = fromMisoString s renderBuilder (VNode _ "doctype" [] []) = "<!doctype html>"@@ -131,13 +131,13 @@               , ns == MATHML               ] -renderBuilder (VComp _ (SomeComponent vcomp_)) =+renderBuilder (VComp _ (SomeComponent props vcomp_)) =   foldMap renderBuilder vkids     where #ifdef SSR-      vkids = [ unsafeCoerce $ (view vcomp_) $ getInitialComponentModel vcomp_ ]+      vkids = [ unsafeCoerce $ (view vcomp_) props (getInitialComponentModel vcomp_) ] #else-      vkids = [ unsafeCoerce $ (view vcomp_) (model vcomp_) ]+      vkids = [ unsafeCoerce $ (view vcomp_) props (model vcomp_) ] #endif renderBuilder (VFrag _ kids) = foldMap renderBuilder kids ----------------------------------------------------------------------------
src/Miso/Navigator.hs view
@@ -52,7 +52,7 @@   -- ^ Successful callback   -> (JSVal -> action)   -- ^ Errorful callback-  -> Effect parent model action+  -> Effect parent props model action getUserMedia UserMedia {..} successful errorful =   withSink $ \sink ->     FFI.getUserMedia audio video@@ -70,7 +70,7 @@   -- ^ Successful callback   -> (JSVal -> action)   -- ^ Errorful callback-  -> Effect parent model action+  -> Effect parent props model action copyClipboard txt successful errorful =   withSink $ \sink ->     FFI.copyClipboard txt@@ -84,7 +84,7 @@ isOnLine   :: (Bool -> action)   -- ^ Successful callback-  -> Effect parent model action+  -> Effect parent props model action isOnLine action = io (action <$> FFI.isOnLine) ----------------------------------------------------------------------------- -- | Type for dealing with 'navigator.mediaDevices.getUserMedia'@@ -107,7 +107,7 @@ geolocation   :: (Geolocation -> action)   -> (GeolocationError -> action)-  -> Effect parent model action+  -> Effect parent props model action geolocation successful errorful = do   withSink $ \sink ->     FFI.geolocation
src/Miso/Runtime.hs view
@@ -51,6 +51,7 @@   , parent   , mailParent   , mailChildren+  , mailAncestors   -- ** WebSocket   , websocketConnect   , websocketConnectJSON@@ -150,18 +151,21 @@ ----------------------------------------------------------------------------- -- | Helper function to abstract out initialization of t'Miso.Types.Component' between top-level API functions. initialize-  :: (Eq parent, Eq model)+  :: (Eq parent, Eq model, Eq props)   => Events   -> ComponentId   -> Hydrate   -> Bool   -- ^ Is the root node being rendered?-  -> Component parent model action+  -> props+  -- ^ Initial props for this component+  -> Component parent props model action   -> IO DOMRef   -- ^ Callback function is used for obtaining the t'Miso.Types.Component' 'DOMRef'.-  -> IO (ComponentState parent model action)-initialize events _componentParentId hydrate isRoot comp@Component {..} getComponentMountPoint = do+  -> IO (ComponentState parent props model action)+initialize events _componentParentId hydrate isRoot initialProps comp@Component {..} getComponentMountPoint = do   _componentId <- freshComponentId+  let _componentProps = initialProps   let     _componentSink = \action -> liftIO $ do       atomicModifyIORef' globalQueue (\q -> (enqueue _componentId action q, ()))@@ -192,7 +196,10 @@       putMVar frame =<< fromJSValUnchecked jsval    let _componentDraw = \newModel -> do-        newVTree <- buildVTree events _componentParentId _componentId Draw _componentSink logLevel (view newModel)+        props <- (^. componentProps) . (IM.! _componentId) <$> readIORef components+        newVTree <-+          buildVTree events _componentParentId _componentId Draw+            _componentSink logLevel (view props newModel)         oldVTree <- liftIO (readIORef _componentVTree)         _frame <- requestAnimationFrame rAFCallback         _timestamp :: Double <- takeMVar frame@@ -201,8 +208,8 @@         liftIO (atomicWriteIORef _componentVTree newVTree)         FFI.flush -  let _componentApplyActions = \(actions :: [action]) model_ comps -> do-        let info = ComponentInfo _componentId _componentParentId _componentDOMRef+  let _componentApplyActions = \(actions :: [action]) model_ comps props -> do +        let info = ComponentInfo _componentId _componentParentId _componentDOMRef props         List.foldl' (\(vcomps, m, ss, dirtySet) a ->           case runEffect (update a) info m of             (n, sss) ->@@ -306,6 +313,13 @@   forever $ do     getBatch >>= \case       Nothing -> wait globalWaiter+      Just (vcompId, [])+        | vcompId < 0 -> do+            -- props propagation, negated 'ComponentId' indicates render-phase only.+            vcomps <- liftIO (readIORef components)+            forM_ (IM.lookup (negate vcompId) vcomps) $ \ComponentState {..} ->+              _componentDraw _componentModel+                                    Just (vcompId, actions) -> do         mounted <- isMounted vcompId         when mounted (run vcompId actions)@@ -322,7 +336,7 @@       (updatedModel, schedules, dirtySet, ComponentState{..}) <- do         atomicModifyIORef' components $ \vcomps -> do           let cs@ComponentState {..} = vcomps IM.! vcompId-          case _componentApplyActions events _componentModel vcomps of+          case _componentApplyActions events _componentModel vcomps _componentProps of             (x, updatedModel, schedules, dirtySet) ->               (x, (updatedModel, schedules, dirtySet, cs))       forM_ schedules $ \case@@ -358,7 +372,7 @@ -- Auxiliary function modifyComponent   :: ComponentId-  -> State (ComponentState parent model action) a+  -> State (ComponentState parent props model action) a   -> IO () modifyComponent vcompId go = liftIO $ do   atomicModifyIORef' components $ \vcomps ->@@ -370,21 +384,21 @@ ---------------------------------------------------------------------------- propagate   :: ComponentId-  -> IntMap (ComponentState p m a)-  -> (IntMap (ComponentState p m a), ComponentIds)+  -> IntMap (ComponentState p props m a)+  -> (IntMap (ComponentState p props m a), ComponentIds) propagate vcompId vcomps =   let dfsState = execState synch (dfs vcomps vcompId)   in (_state dfsState, _visited dfsState) ----------------------------------------------------------------------------- -- | Create an empty DFS state-dfs :: IntMap (ComponentState p m a) -> ComponentId -> DFS p m a+dfs :: IntMap (ComponentState p props m a) -> ComponentId -> DFS p props m a dfs cs vcompId = DFS cs mempty (pure vcompId) ----------------------------------------------------------------------------- type ComponentIds = IntSet ------------------------------------------------------------------------------data DFS p m a+data DFS p props m a   = DFS-  { _state :: IntMap (ComponentState p m a)+  { _state :: IntMap (ComponentState p props m a)     -- ^ global component state to alter   , _visited :: ComponentIds     -- ^ visited set@@ -392,21 +406,21 @@     -- ^ neighbors queue   } ------------------------------------------------------------------------------type Synch p m a x = State (DFS p m a) x+type Synch p props m a x = State (DFS p props m a) x ------------------------------------------------------------------------------visited :: Lens (DFS p m a) (ComponentIds)+visited :: Lens (DFS p props m a) (ComponentIds) visited = lens _visited $ \r x -> r { _visited = x } ------------------------------------------------------------------------------state :: Lens (DFS p m a) (IntMap (ComponentState p m a))+state :: Lens (DFS p props m a) (IntMap (ComponentState p props m a)) state = lens _state $ \r x -> r { _state = x } ------------------------------------------------------------------------------stack :: Lens (DFS p m a) [ComponentId]+stack :: Lens (DFS p props m a) [ComponentId] stack = lens _stack $ \r x -> r { _stack = x } ------------------------------------------------------------------------------synch :: Synch p m a ()+synch :: Synch p props m a () synch = mapM_ go =<< pop   where-    go :: ComponentState p m a -> Synch p m a ()+    go :: ComponentState p props m a -> Synch p props m a ()     go cs = do       seen <- IS.member (cs ^. componentId) <$> use visited       when (not seen) $ do@@ -416,10 +430,10 @@         synch ----------------------------------------------------------------------------- propagateChildren-  :: forall p m a-   . ComponentState p m a+  :: forall p props m a+   . ComponentState p props m a   -> ComponentIds-  -> Synch p m a ()+  -> Synch p props m a () propagateChildren currentState childComponents = do   forM_ (IS.toList childComponents) $ \childId -> do     childState <- unsafeCoerce (IM.! childId) <$> use state@@ -434,9 +448,9 @@       visit childId     where       process-        :: ComponentState m child a+        :: ComponentState m props child a         -> Binding m child-        -> Synch p m a (ComponentState m child a)+        -> Synch p props m a (ComponentState m props child a)       process childState = \case         ParentToChild getCurrentField setChildField -> do           let currentChildModel = childState ^. componentModel@@ -452,10 +466,10 @@           pure childState ----------------------------------------------------------------------------- propagateParent-  :: forall p m a-   . ComponentState p m a+  :: forall p props m a+   . ComponentState p props m a   -> ComponentId-  -> Synch p m a ()+  -> Synch p props m a () propagateParent currentState parentId_ =   IM.lookup parentId_ <$> use state >>= mapM_ \case     parentState -> do@@ -470,9 +484,9 @@         visit parentId_   where     process-      :: ComponentState x p a+      :: ComponentState x props p a       -> Binding p m-      -> Synch p m a (ComponentState x p a)+      -> Synch p props m a (ComponentState x props p a)     process parentState = \case       ChildToParent setParentField getCurrentField -> do         let currentParentModel = parentState ^. componentModel@@ -487,13 +501,13 @@       _ ->         pure parentState ------------------------------------------------------------------------------markVisited :: ComponentId -> Synch p m a ()+markVisited :: ComponentId -> Synch p props m a () markVisited vcompId = visited.at vcompId ?= () ------------------------------------------------------------------------------visit :: ComponentId -> Synch p m a ()+visit :: ComponentId -> Synch p props m a () visit vcompId = stack %= (vcompId:) ------------------------------------------------------------------------------pop :: Synch p m a (Maybe (ComponentState p m a))+pop :: Synch p props m a (Maybe (ComponentState p props m a)) pop = use stack >>= \case   [] ->     pure Nothing@@ -502,19 +516,20 @@     use (state . at x) ----------------------------------------------------------------------------- initialDraw-  :: Eq m+  :: (Eq m, Eq props)   => m   -> Events   -> Hydrate   -> Bool-  -> Component p m a-  -> ComponentState p m a+  -> Component p props m a+  -> ComponentState p props m a   -> IO () initialDraw initializedModel events hydrate isRoot Component {..} ComponentState {..} = do #ifdef BENCH   start <- FFI.now #endif-  vtree <- buildVTree events _componentParentId _componentId hydrate _componentSink logLevel (view initializedModel)+  vtree <- buildVTree events _componentParentId _componentId hydrate _componentSink logLevel+    (view _componentProps initializedModel) #ifdef BENCH   end <- FFI.now   when isRoot $ FFI.consoleLog $ ms (printf "buildVTree: %.3f ms" (end - start) :: String)@@ -533,7 +548,7 @@             else do               newTree <-                 buildVTree events _componentParentId _componentId Draw-                  _componentSink logLevel (view initializedModel)+                  _componentSink logLevel (view _componentProps initializedModel)               Diff.diff Nothing (Just newTree) _componentDOMRef               liftIO (atomicWriteIORef _componentVTree newTree)         else@@ -581,6 +596,13 @@   q & queue %~ IM.insertWith (flip (<>)) vcompId (S.singleton action)     & queueSchedule %~ (S.|> vcompId) -----------------------------------------------------------------------------+-- | Used to fast track to render phase, bypassing commit phase. Used in 'props'+-- feature.+enqueueSchedule :: ComponentId -> IO ()+enqueueSchedule vcompId =+  atomicModifyIORef' globalQueue $ \q ->+     (q & queueSchedule %~ (S.|> negate vcompId), ())+----------------------------------------------------------------------------- -- | Case on queue schedule, get first item, span on the rest of queueSchedule, get length. -- set schedule with whatever remains. --@@ -596,8 +618,9 @@     S.Empty -> Nothing     sched@(vcompId S.:<| leftover) ->       case q ^. queue . at vcompId of-        Nothing -> -- dmj: if unmount occurred, just pop the schedule-          Just (vcompId, [], q & queueSchedule .~ leftover)+        Nothing ->+          let (_, remaining) = S.spanl (== vcompId) sched+          in Just (vcompId, [], q & queueSchedule .~ remaining)         Just actions ->           case S.spanl (==vcompId) sched of             (scheduled, remaining) ->@@ -632,27 +655,30 @@ {-# NOINLINE globalQueue #-} globalQueue = unsafePerformIO (newIORef emptyQueue) ------------------------------------------------------------------------------componentId :: Lens (ComponentState parent model action) ComponentId+componentId :: Lens (ComponentState parent props model action) ComponentId componentId = lens _componentId $ \record field -> record { _componentId = field } ------------------------------------------------------------------------------parentId :: Lens (ComponentState parent model action) ComponentId+parentId :: Lens (ComponentState parent props model action) ComponentId parentId = lens _componentParentId $ \record field -> record { _componentParentId = field } ------------------------------------------------------------------------------children :: Lens (ComponentState parent model action) (ComponentIds)+children :: Lens (ComponentState parent props model action) (ComponentIds) children = lens _componentChildren $ \record field -> record { _componentChildren = field } ------------------------------------------------------------------------------componentTopics :: Lens (ComponentState parent model action) (Map MisoString (Value -> IO ()))+componentTopics :: Lens (ComponentState parent props model action) (Map MisoString (Value -> IO ())) componentTopics = lens _componentTopics $ \record field -> record { _componentTopics = field } ------------------------------------------------------------------------------isDirty :: Lens (ComponentState parent model action) Bool+isDirty :: Lens (ComponentState parent props model action) Bool isDirty = lens _componentIsDirty $ \record field -> record { _componentIsDirty = field } ------------------------------------------------------------------------------componentModel :: Lens (ComponentState parent model action) model+componentModel :: Lens (ComponentState parent props model action) model componentModel = lens _componentModel $ \record field -> record { _componentModel = field } ------------------------------------------------------------------------------componentBindings :: Lens (ComponentState p m a) [Binding p m]+componentBindings :: Lens (ComponentState p props m a) [Binding p m] componentBindings = lens _componentBindings $ \record field -> record { _componentBindings = field } -----------------------------------------------------------------------------+componentProps :: Lens (ComponentState parent props model action) props+componentProps = lens _componentProps $ \record field -> record { _componentProps = field }+----------------------------------------------------------------------------- -- | Hydrate avoids calling @diff@, and instead calls @hydrate@ -- 'Draw' invokes 'Miso.Diff.diff' data Hydrate@@ -661,12 +687,14 @@   deriving (Show, Eq) ----------------------------------------------------------------------------- -- | t'Miso.Types.Component' state, data associated with the lifetime of a t'Miso.Types.Component'-data ComponentState parent model action+data ComponentState parent props model action   = ComponentState   { _componentId :: ComponentId   -- ^ The ID of the current t'Miso.Types.Component'   , _componentParentId :: ComponentId   -- ^ The ID of the t'Miso.Types.Component''s parent+  , _componentProps :: props+  -- ^ The current props passed to this t'Miso.Types.Component'   , _componentSubThreads :: IORef (Map MisoString ThreadId)   -- ^ Mapping of all 'Sub' in use by t'Miso.Types.Component'   , _componentDOMRef :: DOMRef@@ -694,12 +722,14 @@   , _componentApplyActions       :: [action]       -> model-      -> IntMap (ComponentState parent model action)-      -> (IntMap (ComponentState parent model action), model, [Schedule action], ComponentIds)+      -> IntMap (ComponentState parent props model action)+      -> props+      -> (IntMap (ComponentState parent props model action), model, [Schedule action], ComponentIds)   -- ^ t'Miso.Types.Component' actions application   , _componentTopics :: Map MisoString (Value -> IO ())   -- ^ t'Miso.Types.Component' topics using for Pub Sub async communication.   , _componentChildren :: ComponentIds+  -- ^ 'IntSet' of children t'Miso.Types.ComponentId'   } ----------------------------------------------------------------------------- -- | A @Topic@ represents a place to send and receive messages. @Topic@ is used to facilitate@@ -804,7 +834,7 @@   => Topic message   -> (message -> action)   -> (MisoString -> action)-  -> Effect parent model action+  -> Effect parent props model action subscribe (Topic topicName) successful errorful = do   ComponentInfo {..} <- ask   withSink $ \sink ->@@ -851,7 +881,7 @@ -- See 'subscribe' for more use. -- -- @since 1.9.0.0-unsubscribe :: Topic message -> Effect parent model action+unsubscribe :: Topic message -> Effect parent props model action unsubscribe (Topic topicName) = do   ComponentInfo {..} <- ask   io_ $ modifyComponent _componentInfoId $ do@@ -880,11 +910,7 @@ --   , button_ [ onClick AddOne ] [ "+" ] --   , button_ [ onClick SubtractOne ] [ "-" ] --   , component_ (client_ "client 1")---     [ onMountedWith Mount---     ] --   , component_ (client_ "client 2")---     [ onMountedWith Mount---     ] --   ] where --       update_ :: Action -> Effect parent () Action --       update_ = \case@@ -944,7 +970,7 @@ -- -- This is a global t'Miso.Types.Component' @Map@ that holds the state of all currently -- mounted t'Miso.Types.Component's-components :: IORef (IntMap (ComponentState parent model action))+components :: IORef (IntMap (ComponentState parent props model action)) {-# NOINLINE components #-} components = unsafePerformIO (newIORef mempty) -----------------------------------------------------------------------------@@ -958,14 +984,14 @@ ----------------------------------------------------------------------------- -- | Drains the event queue before unmounting, executed synchronously. drain-  :: ComponentState parent model action+  :: ComponentState parent props model action   -> IO () drain ComponentState {..} = do   drainQueueAt _componentId >>= \case     [] -> pure ()     actions -> do        vcomps <- readIORef components-       case _componentApplyActions actions _componentModel vcomps of+       case _componentApplyActions actions _componentModel vcomps _componentProps of          (newVComps, _, schedules, _) -> do            forM_ schedules $ \case              -- dmj: process all actions synchronously during unmount@@ -978,13 +1004,13 @@            atomicWriteIORef components newVComps ----------------------------------------------------------------------------- -- | Post unmount call to drop the <style> and <script> in <head>-unloadScripts :: ComponentState parent model action -> IO ()+unloadScripts :: ComponentState parent props model action -> IO () unloadScripts ComponentState {..} = do   head_ <- FFI.getHead   forM_ _componentScripts (FFI.removeChild head_) ----------------------------------------------------------------------------- -- | Helper to drop all lifecycle and mounting hooks if defined.-freeLifecycleHooks :: ComponentState parent model action -> IO ()+freeLifecycleHooks :: ComponentState parent props model action -> IO () freeLifecycleHooks ComponentState {..} = do   VTree (Object comp) <- liftIO (readIORef _componentVTree)   mapM_ freeFunction =<< fromJSVal =<< comp ! ("mount" :: MisoString)@@ -992,7 +1018,7 @@ ----------------------------------------------------------------------------- -- | Helper function for cleanly destroying a t'Miso.Types.Component' unmountComponent-  :: ComponentState parent model action+  :: ComponentState parent props model action   -> IO () unmountComponent cs@ComponentState {..} = do   liftIO (mapM_ killThread =<< readIORef _componentSubThreads)@@ -1001,9 +1027,10 @@   finalizeEventSources _componentId   unloadScripts cs   freeLifecycleHooks cs-  liftIO $ modifyComponent _componentParentId $ do-    children.at _componentId .= Nothing-  liftIO $ atomicModifyIORef' components $ \m -> (IM.delete _componentId m, ())+  liftIO $ do+    modifyComponent _componentParentId $ do+      children.at _componentId .= Nothing+    atomicModifyIORef' components $ \m -> (IM.delete _componentId m, ())   FFI.unmountComponent _componentId ----------------------------------------------------------------------------- resetComponentState :: IO () -> IO ()@@ -1033,12 +1060,12 @@   -> View model action   -> IO VTree buildVTree events_ parentId_ vcompId hydrate snk logLevel_ = \case-  VComp maybeKey (SomeComponent app) -> do+  VComp maybeKey (SomeComponent newProps app) -> do     vcomp_ <- create      mountCallback <- do       syncCallback1' $ \parent_ -> do-        ComponentState {..} <- initialize events_ vcompId hydrate False app (pure parent_)+        ComponentState {..} <- initialize events_ vcompId hydrate False newProps app (pure parent_)         modifyComponent vcompId (children %= IS.insert _componentId)         vtree <- toJSVal =<< readIORef _componentVTree         FFI.set "parent" vcomp_ (Object vtree)@@ -1056,6 +1083,18 @@             forM_ (unmount app) (_componentSink componentState)             unmountComponent componentState +    -- When props are present, install a diffProps callback.+    -- Comparison happens in Haskell against _componentLastProps — no round-trip.+    -- TypeScript calls diffProps() unconditionally; Haskell decides whether to dispatch.+    diffPropsCallback <- toJSVal =<< do+      syncCallback $ do+        componentId_ <- fromJSValUnchecked =<< vcomp_ ! ("componentId" :: MisoString)+        currentProps <- _componentProps . (IM.! componentId_) <$> readIORef components+        when (currentProps /= newProps) $ do+          modifyComponent componentId_ (componentProps .= newProps)+          enqueueSchedule componentId_++    FFI.set "diffProps" diffPropsCallback vcomp_     FFI.set "child" jsNull vcomp_     forM_ maybeKey (\key -> FFI.set "key" key vcomp_)     FFI.set "mount" mountCallback vcomp_@@ -1161,7 +1200,7 @@         FFI.set k v (Object cssObj) ----------------------------------------------------------------------------- -- | Registers components in the global state-registerComponent :: MonadIO m => ComponentState parent model action -> m ()+registerComponent :: MonadIO m => ComponentState parent props model action -> m () registerComponent componentState = liftIO $   atomicModifyIORef' components $ \cs ->     (IM.insert (_componentId componentState) componentState cs, ())@@ -1221,7 +1260,7 @@   -- ^ The key used to track the 'Sub'   -> Sub action   -- ^ The 'Sub'-  -> Effect parent model action+  -> Effect parent props model action startSub subKey sub = do   ComponentInfo {..} <- ask   io_ $ do@@ -1260,7 +1299,7 @@   :: ToMisoString subKey   => subKey   -- ^ The key used to stop the 'Sub'-  -> Effect parent model action+  -> Effect parent props model action stopSub subKey = do   vcompId <- asks _componentInfoId   io_ $ do@@ -1277,7 +1316,7 @@ -- | Send any @ToJSON message => message@ to a t'Miso.Types.Component' mailbox, by 'ComponentId' -- -- @--- io_ $ mail componentId ("test message" :: MisoString) :: Effect parent model action+-- io_ $ mail componentId ("test message" :: MisoString) :: Effect parent props model action -- @ -- -- @since 1.9.0.0@@ -1300,7 +1339,7 @@ -- | Send any @ToJSON message => message@ to the parent's t'Miso.Types.Component' mailbox -- -- @--- mailParent ("test message" :: MisoString) :: Effect parent model action+-- mailParent ("test message" :: MisoString) :: Effect parent props model action -- @ -- -- @since 1.9.0.0@@ -1308,15 +1347,42 @@   :: ToJSON message   => message   -- ^ Message to send-  -> Effect parent model action+  -> Effect parent props model action mailParent msg = do   ComponentInfo {..} <- ask   io_ (mail _componentInfoParentId msg) -----------------------------------------------------------------------------+-- | Send any @ToJSON message => message@ to all ancestor t'Miso.Types.Component' 'mailbox'.+--+-- This function walks the t'Miso.Types.Component' ancestor hierarchy, delivering mail+-- along the way.+--+-- @+-- mailAncestors ("test message" :: MisoString) :: Effect parent props model action+-- @+--+-- @since 1.11.0.0+mailAncestors+  :: ToJSON message+  => message+  -- ^ Message to send+  -> Effect parent props model action+mailAncestors msg = do+  ComponentInfo {..} <- ask+  io_ (climb _componentInfoParentId)+    where+      climb vcompId = do+        mail vcompId msg+        IM.lookup vcompId <$> readIORef components >>= \case+          Nothing -> pure ()+          Just cs -> climb (_componentParentId cs)+----------------------------------------------------------------------------- -- | Send any @ToJSON message => message@ to the children's t'Miso.Types.Component' mailbox --+-- N.B. this is only relevant for immediate descendants (not all descendants).+-- -- @--- mailChildren ("test message" :: MisoString) :: Effect parent model action+-- mailChildren ("test message" :: MisoString) :: Effect parent props model action -- @ -- -- @since 1.9.0.0@@ -1324,7 +1390,7 @@   :: ToJSON message   => message   -- ^ Message to send-  -> Effect parent model action+  -> Effect parent props model action mailChildren msg = do   ComponentInfo {..} <- ask   io_ $ do@@ -1368,7 +1434,7 @@   -- ^ Successful callback   -> action   -- ^ Errorful callback-  -> Effect parent model action+  -> Effect parent props model action parent successful errorful = do   ComponentInfo {..} <- ask   withSink $ \sink -> do@@ -1381,7 +1447,7 @@ -- -- @ ----- update :: action -> Effect parent model action+-- update :: action -> Effect parent props model action -- update _ = broadcast (String "public service announcement") -- @ --@@ -1391,7 +1457,7 @@   => ToJSON message   => message   -- ^ Message to broadcast to all other 'Component'-  -> Effect parent model action+  -> Effect parent props model action broadcast msg = do   ComponentInfo {..} <- ask   io_ $ do@@ -1430,7 +1496,7 @@   -- ^ onMessage   -> (MisoString -> action)   -- ^ onError-  -> Effect parent model action+  -> Effect parent props model action websocketConnectText url onOpen onClosed onMessage onError =   websocketCore $ \webSocketId sink ->     FFI.websocketConnect url@@ -1454,7 +1520,7 @@   -- ^ onMessage   -> (MisoString -> action)   -- ^ onError-  -> Effect parent model action+  -> Effect parent props model action websocketConnectBLOB url onOpen onClosed onMessage onError =   websocketCore $ \webSocketId sink ->     FFI.websocketConnect url@@ -1478,7 +1544,7 @@   -- ^ onMessage   -> (MisoString -> action)   -- ^ onError-  -> Effect parent model action+  -> Effect parent props model action websocketConnectArrayBuffer url onOpen onClosed onMessage onError =   websocketCore $ \webSocketId sink ->     FFI.websocketConnect url@@ -1503,7 +1569,7 @@   -- ^ onMessage   -> (MisoString -> action)   -- ^ onError-  -> Effect parent model action+  -> Effect parent props model action websocketConnectJSON url onOpen onClosed onMessage onError =   websocketCore $ \webSocketId sink ->     FFI.websocketConnect url@@ -1532,7 +1598,7 @@   -- ^ onMessage   -> (MisoString -> action)   -- ^ onError-  -> Effect parent model action+  -> Effect parent props model action websocketConnect url onOpen onClosed onMessage onError =   websocketCore $ \webSocketId sink ->     FFI.websocketConnect url@@ -1552,7 +1618,7 @@ -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket> websocketCore   :: (WebSocket -> Sink action -> IO Socket)-  -> Effect parent model action+  -> Effect parent props model action websocketCore core = do   ComponentInfo {..} <- ask   withSink $ \sink -> do@@ -1590,7 +1656,7 @@           (IM.delete vcompId websockets, ()) ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close>-websocketClose :: WebSocket -> Effect parent model action+websocketClose :: WebSocket -> Effect parent props model action websocketClose socketId = do   ComponentInfo {..} <- ask   io_ $ do@@ -1617,7 +1683,7 @@   :: ToJSON value   => WebSocket   -> Payload value-  -> Effect parent model action+  -> Effect parent props model action websocketSend socketId msg = do   ComponentInfo {..} <- ask   io_ $ do@@ -1638,7 +1704,7 @@ -- -- If the t'WebSocket' identifier does not exist a 'CLOSED' is returned. ---socketState :: WebSocket -> (SocketState -> action) -> Effect parent model action+socketState :: WebSocket -> (SocketState -> action) -> Effect parent props model action socketState socketId callback = do   ComponentInfo {..} <- ask   withSink $ \sink -> do@@ -1766,7 +1832,7 @@   -- ^ onMessage   -> (MisoString -> action)   -- ^ onError-  -> Effect parent model action+  -> Effect parent props model action eventSourceConnectText url onOpen onMessage onError =   eventSourceCore $ \eventSourceId sink -> do     FFI.eventSourceConnect url@@ -1789,7 +1855,7 @@   -- ^ onMessage   -> (MisoString -> action)   -- ^ onError-  -> Effect parent model action+  -> Effect parent props model action eventSourceConnectJSON url onOpen onMessage onError =   eventSourceCore $ \eventSourceId sink -> do     FFI.eventSourceConnect url@@ -1805,7 +1871,7 @@ -- | <https://developer.mozilla.org/en-US/docs/Web/API/EventSource/EventSource> eventSourceCore   :: (EventSource -> Sink action -> IO Socket)-  -> Effect parent model action+  -> Effect parent props model action eventSourceCore core = do   ComponentInfo {..} <- ask   withSink $ \sink -> do@@ -1828,7 +1894,7 @@       atomicModifyIORef' eventSourceConnectionIds (\x -> (x + 1, x)) ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/EventSource/close>-eventSourceClose :: EventSource -> Effect parent model action+eventSourceClose :: EventSource -> Effect parent props model action eventSourceClose socketId = do   ComponentInfo {..} <- ask   io_ $ do@@ -1892,11 +1958,11 @@   :: (Eq parent, Eq model)   => Events   -> Hydrate-  -> Component parent model action+  -> Component parent () model action   -> IO () initComponent events hydrate vcomp_@Component {..} = withJS $ do   root <- Diff.mountElement (getMountPoint mountPoint)-  void $ initialize events rootComponentId hydrate True vcomp_ (pure root)+  void $ initialize events rootComponentId hydrate True () vcomp_ (pure root) #if __GLASGOW_HASKELL__ > 865   flip labelThread "scheduler" =<< forkIO scheduler #else
src/Miso/Types.hs view
@@ -66,6 +66,8 @@   -- ** Component mounting   , (+>)   , mount_+  , mountWithProps_+  , mountWithProps   -- ** Key combinators   , keyed   -- ** Fragment combinators@@ -114,7 +116,7 @@ import           Miso.CSS.Types (StyleSheet) ----------------------------------------------------------------------------- -- | Application entry point-data Component parent model action+data Component parent props model action   = Component   { model :: model   -- ^ Initial model@@ -125,9 +127,9 @@ #endif   -- ^ Optional 'IO' to load component 'model' state, such as reading data from page.   --   The resulting 'model' is only used during initial hydration, not on remounts.-  , update :: action -> Effect parent model action+  , update :: action -> Effect parent props model action   -- ^ Updates model, optionally providing effects.-  , view :: model -> View model action+  , view :: props -> model -> View model action   -- ^ Draws 'View'   , subs :: [ Sub action ]   -- ^ Subscriptions to run during application lifetime@@ -228,11 +230,11 @@ component   :: model   -- ^ model-  -> (action -> Effect parent model action)+  -> (action -> Effect parent props model action)   -- ^ update-  -> (model -> View model action)+  -> (props -> model -> View model action)   -- ^ view-  -> Component parent model action+  -> Component parent props model action component m u v = Component   { model = m   , hydrateModel = Nothing@@ -254,11 +256,11 @@ vcomp   :: model   -- ^ model-  -> (action -> Effect parent model action)+  -> (action -> Effect parent props model action)   -- ^ update-  -> (model -> View model action)+  -> (props -> model -> View model action)   -- ^ view-  -> Component parent model action+  -> Component parent props model action vcomp = component   ----------------------------------------------------------------------------- -- | A top-level t'Miso.Types.Component' can have no @parent@.@@ -274,7 +276,7 @@ -- | A miso application is a top-level t'Miso.Types.Component', which has no @parent@. -- This is enforced by specializing the @parent@ type parameter to 'ROOT'. ---type App model action = Component ROOT model action+type App model action = Component ROOT () model action ----------------------------------------------------------------------------- -- | Logging configuration for debugging Miso internals (useful to see if prerendering is successful) data LogLevel@@ -309,8 +311,8 @@ ----------------------------------------------------------------------------- -- | Existential wrapper allowing nesting of t'Miso.Types.Component' in t'Miso.Types.Component' data SomeComponent parent-   = forall model action . Eq model-  => SomeComponent (Component parent model action)+   = forall model action props . (Eq model, Eq props)+  => SomeComponent props (Component parent props model action) ----------------------------------------------------------------------------- -- | Like '+>' but operates on any 'View', not just 'Component'. --@@ -380,14 +382,14 @@ -- -- @since 1.9.0.0 (+>)-  :: forall child model action a . Eq child+  :: forall child childAction model action . Eq child   => MisoString   -- ^ 'VComp' 'key_'-  -> Component model child action+  -> Component model () child childAction   -- ^ 'Component'-  -> View model a+  -> View model action infixr 0 +>-key +> comp = VComp (Just (toKey key)) (SomeComponent comp)+key +> comp = VComp (Just (toKey key)) (SomeComponent () comp) ----------------------------------------------------------------------------- -- | t'Miso.Types.Component' mounting combinator. --@@ -396,6 +398,46 @@ -- the two t'Miso.Types.Component', to ensure unmounting and mounting occurs. -- -- @+-- mountWithProps someProps $ component model noop $ \\m ->+--  div_ [ id_ "foo" ] [ text (ms m) ]+-- @+--+-- @since 1.11.0.0+mountWithProps+  :: (Eq child, Eq props)+  => props+  -- ^ 'props' to use+  -> Component parent props child action+  -- ^ 'Component' to mount+  -> View parent a+mountWithProps props comp  = VComp Nothing (SomeComponent props comp)+-----------------------------------------------------------------------------+-- | t'Miso.Types.Component' mounting combinator.+--+-- @+-- mountWithProps_ "key" someProps $ component model noop $ \\m ->+--  div_ [ id_ "foo" ] [ text (ms m) ]+-- @+--+-- @since 1.11.0.0+mountWithProps_+  :: (Eq child, Eq props)+  => MisoString+  -- ^ 'key' to use+  -> props+  -- ^ 'props' to use+  -> Component parent props child action+  -- ^ 'Component' to mount+  -> View parent a+mountWithProps_ key props comp  = VComp (Just (Key key)) (SomeComponent props comp)+-----------------------------------------------------------------------------+-- | t'Miso.Types.Component' mounting combinator.+--+-- Note: only use this if you're certain you won't be diffing two t'Miso.Types.Component'+-- against each other. Otherwise, you will need a key to distinguish between+-- the two t'Miso.Types.Component', to ensure unmounting and mounting occurs.+--+-- @ -- mount_ $ component model noop $ \\m -> --  div_ [ id_ "foo" ] [ text (ms m) ] -- @@@ -403,10 +445,10 @@ -- @since 1.9.0.0 mount_   :: Eq child-  => Component model child a+  => Component parent () child childAction   -- ^ 'Component' to mount-  -> View model action-mount_ comp = VComp Nothing (SomeComponent comp)+  -> View parent action+mount_ comp = VComp Nothing (SomeComponent () comp) ----------------------------------------------------------------------------- -- | DOM element namespace. data Namespace
src/Miso/WebSocket.hs view
@@ -61,7 +61,7 @@   -- ^ @onMessage@ is a callback invoked when a message has been received from the t'WebSocket' server.   -> (MisoString -> action)   -- ^ Error message callback-  -> Effect parent model action+  -> Effect parent props model action connect = websocketConnect ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket>@@ -80,7 +80,7 @@   -- ^ @onMessage@ is a callback invoked when a JSON-encoded message has been received from the t'WebSocket' server.   -> (MisoString -> action)   -- ^ Error message callback-  -> Effect parent model action+  -> Effect parent props model action connectJSON = websocketConnectJSON ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket>@@ -98,7 +98,7 @@   -- ^ @onMessage@ is a callback invoked when a text-encoded message has been received from the t'WebSocket' server.   -> (MisoString -> action)   -- ^ Error message callback-  -> Effect parent model action+  -> Effect parent props model action connectText = websocketConnectText ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket>@@ -116,7 +116,7 @@   -- ^ @onMessage@ is a callback invoked when a binary-encoded message has been received from the t'WebSocket' server.   -> (MisoString -> action)   -- ^ @onError@ callback-  -> Effect parent model action+  -> Effect parent props model action connectBLOB = websocketConnectBLOB ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket>@@ -134,7 +134,7 @@   -- ^ @onMessage@ is a callback invoked when an t'ArrayBuffer' message has been received from the t'WebSocket' server.   -> (MisoString -> action)   -- ^ @onError@ callback-  -> Effect parent model action+  -> Effect parent props model action connectArrayBuffer = websocketConnectArrayBuffer ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send>@@ -147,7 +147,7 @@ -- instance ToJSON Person where --   toJSON (Person name age) = object [ "name" .= name, "age" .= age ] ----- test :: WebSocket -> Effect parent model action+-- test :: WebSocket -> Effect parent props model action -- test connection = do --   sendJSON (connection :: WebSocket) (Person "alice" 42) --   sendJSON (connection :: WebSocket) (Person "bob" 42)@@ -160,7 +160,7 @@   -- ^ t'WebSocket' descriptor required to send a message to the server.   -> json   -- ^ A JSON-encoded message-  -> Effect parent model action+  -> Effect parent props model action sendJSON socket x = websocketSend socket (JSON x) ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send>@@ -169,7 +169,7 @@   -- ^ t'WebSocket' descriptor required to send a message to the server.   -> Blob   -- ^ An t'Blob' payload to send to the t'WebSocket' server-  -> Effect parent model action+  -> Effect parent props model action sendBLOB socket x = websocketSend @() socket (blob x) ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send>@@ -178,7 +178,7 @@   -- ^ t'WebSocket' descriptor required to send a message to the server.   -> ArrayBuffer   -- ^ An t'ArrayBuffer' payload to send to the t'WebSocket' server-  -> Effect parent model action+  -> Effect parent props model action sendArrayBuffer socket x = websocketSend @() socket (arrayBuffer x) ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send>@@ -187,7 +187,7 @@   -- ^ t'WebSocket' descriptor required to send a message to the server.   -> MisoString   -- ^ A text payload to send to t'WebSocket' server-  -> Effect parent model action+  -> Effect parent props model action sendText socket x = websocketSend @() socket (TEXT x) ----------------------------------------------------------------------------- -- | <https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close>@@ -199,6 +199,6 @@ close   :: WebSocket   -- ^ t'WebSocket' descriptor required to close the socket on the server.-  -> Effect parent model action+  -> Effect parent props model action close = websocketClose -----------------------------------------------------------------------------