thomashoneyman/purescript-halogen-hooks

EventSource.emit docs are misleading for Hooks

milesfrain opened this issue · 4 comments

A fix is possible in the main Halogen code, but the issue only affects Hooks users, so I wouldn't consider it a regular Halogen issue.

The help docs for emit are a bit too specific, where a is assumed to be an "action".

emit :: forall m a. Emitter m a -> a -> m Unit

Emits an action via the emitter. For example:

data Action = Notify String

myEventSource = EventSource.affEventSource \emitter -> do
  Aff.delay (Milliseconds 1000.0)
  EventSource.emit emitter (Notify "hello")
  pure mempty

This assumption is fine for regular Halogen, and I can't think of a situation where you'd want to use anything besides a component's Action type, but this is misleading for usage with Hooks because a needs to be HookM m Unit.

I don't know what the best strategy is for improving Halogen docs that require a different interpretation for Hooks. Making the Halogen docs too generic may be more confusing for beginners. Perhaps more Hooks examples would help. There's nothing available yet demonstrating effectEventSource and affEventSource.

For context here's a partial Ace example with effectEventSource. Considering adding something like this to the cookbook.

    content /\ setContent <- useStateFn HK.put "some content"
    document /\ setDocument <- useStateFn HK.put (Nothing :: Maybe Document)
    HK.useLifecycleEffect do
      doc <-
        liftEffect do
          -- Create an editor
          editor <- Ace.edit "editor" Ace.ace
          session <- Editor.getSession editor
          docInner <- Session.getDocument session
          _ <- Document.setValue content docInner
          _ <- Editor.navigateFileStart editor
          pure docInner
      -- Ignoring subscription ID
      _ <-
        HK.subscribe do
          ES.effectEventSource \emitter -> do
            -- Ignoring DocumentEvent
            Document.onChange doc \_ -> do
              str <- Document.getValue doc
              ES.emit emitter $ setContent str
            -- No finalizer
            pure mempty
      setDocument $ Just doc
      pure Nothing

Thanks for pointing this out, @milesfrain. I think there are two things we can do for now, and maybe we can do even more in the future to make this clear.

First, it's a decent approximation to replace any use of Action in Halogen with HookM m Unit in Hooks. In some cases it's not even an approximation, it's the actual case: for example, the HTML type used in Hooks is the same one as that used in Halogen, except that it uses HookM m Unit as the action type. So if you read in the documentation for emit that it "emits an action via the emitter", then in Hooks that means you would emit a HookM m Unit via the emitter.

Second, I'm happy to add an example to this repository that uses subscriptions and event sources, as there is no existing example. Ideally it would be something smaller than the Ace example (perhaps a timer or something like that) just to avoid needing to keep up to date with a third-party component.

I'm open to other suggestions for how to make this "action" distinction more clear as well.

Just FYI. TimeHalogen in the cookbook is using the affEventSource, so there's already an example for that.

I've added labels for this as it's something that could be added to the project documentation (even if just by copy/pasting my description into the docs somewhere).

is this issue still relevant now that this functionality got moved into halogen-subscriptions?