jsdom-extras: Convenience utilities for JSDOM

[ bsd3, library, web ] [ Propose Tags ] [ Report a vulnerability ]

Handy javascript functions and bindings for web development


[Skip to Readme]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1.0.0, 0.1.1.0
Change log CHANGELOG.md
Dependencies aeson (>=2.0 && <2.3), base (>=4.11 && <4.22), jsaddle (>=0.9.8 && <0.10), lens (>=5.0.1 && <5.4), text (>=1.2.4 && <2.2) [details]
License BSD-3-Clause
Copyright 2024 Obsidian Systems LLC
Author Obsidian Systems LLC
Maintainer maintainer@obsidian.systems
Category Web
Source repo head: git clone https://github.com/obsidiansystems/jsdom-extras
Uploaded by abrar at 2025-10-20T04:16:45Z
Distributions
Downloads 34 total (4 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for jsdom-extras-0.1.1.0

[back to package description]

jsdom-extras

Convenience utilities for working with JSDOM / JSaddle from Haskell. This package wraps a few common patterns you’ll reach for in browser-ish code: console logging, JSON ↔︎ JSVal conversion, small object helpers, and a tiny utility to wait for globals to appear.

Motivation If you’re doing Reflex-DOM or JSaddle work, you often need to bridge aeson values, poke at JS objects, or ensure a script on the page has loaded before using it. jsdom-extras provides a small, typed toolkit for that.


Features

  • Console logging via console.log without requiring Show or manual conversions.
  • JSON helpers: Value ↔︎ JSVal that work on both GHCJS and JSaddle-native backends.
  • Object helpers: Build, decompose, and query JavaScript Objects in a few lines.
  • Wait for globals: Poll for a window global and run code once it’s available.

Quick start

Below are small, self‑contained snippets. All examples assume:

{-# LANGUAGE OverloadedStrings #-}
import Language.Javascript.JSaddle (JSM, JSVal, MonadJSM)
import qualified JSDOM.Extras.ConsoleLog as C
import qualified JSDOM.Extras.JSON       as J
import qualified JSDOM.Extras.Object     as O
import qualified JSDOM.Extras.WaitForJS  as W

1) Console logging

hello :: MonadJSM m => m ()
hello = C.consoleLog ("Hello from Haskell!" :: JSM.String)

No Show burden: anything with ToJSVal is fair game.

2) JSON ↔︎ JSVal

import Data.Aeson (Value(..), object, (.=))

mkUser :: JSM JSVal
mkUser = J.jsValFromJSON (object ["name" .= ("Ada" :: String), "id" .= (1 :: Int)])

roundTrip :: JSVal -> JSM (Maybe Value)
roundTrip v = J.jsValToJSON v

stringified :: JSVal -> JSM JSM.String
stringified v = J.stringify v

parsed :: JSM JSVal
parsed = J.parse =<< J.toJSVal ("{\"ok\":true}" :: JSM.String)

These functions are platform‑independent:

  • On GHCJS, conversions use toJSVal/fromJSVal.
  • On JSaddle native, we reuse JSaddle’s internal JSON bridges.

3) Object helpers

mkObj :: MonadJSM m => m O.Object
mkObj = O.toObject [("answer", 42 :: Int), ("name", "Ada" :: JSM.String)]

readObj :: MonadJSM m => O.Object -> m [(JSM.String, JSVal)]
readObj = O.fromObject

findKey :: MonadJSM m => O.Object -> m (Maybe JSVal)
findKey o = O.lookup "answer" o

noop :: O.JSCallAsFunction
noop = O.doNothing

lookup gracefully treats null and undefined as Nothing, and toMaybe is exposed if you need it directly.

4) Wait for a global and use it

Useful when a script tag populates window.SomeLib asynchronously.

useWhenReady :: MonadJSM m => m ()
useWhenReady = W.withGlobalJS "SomeLib" $ \lib -> do
  -- do something with `lib :: JSVal`
  C.consoleLog ("SomeLib is ready" :: JSM.String)

waitForGlobalJS polls at ~250ms intervals until the value is present (neither null nor undefined). If you want a non‑blocking probe, use getGlobalJS which returns Maybe JSVal.


API reference

The library exposes four modules:

  • JSDOM.Extras.ConsoleLog

    • consoleLog :: (MonadJSM m, ToJSVal a) => a -> m ()
  • JSDOM.Extras.JSON

    • jsValFromJSON :: Value -> JSM JSVal
    • jsValToJSON :: JSVal -> JSM (Maybe Value)
    • stringify :: MonadJSM m => JSVal -> m JSM.String
    • parse :: MonadJSM m => JSVal -> m JSVal
  • JSDOM.Extras.Object

    • type ToJSObject k v = (ToJSString k, ToJSVal v)
    • singleton :: (ToJSObject a b, MonadJSM m) => a -> b -> m Object
    • toObject :: (MonadJSM m, ToJSObject a b) => [(a, b)] -> m Object
    • fromObject :: MonadJSM m => Object -> m [(JSM.String, JSVal)]
    • lookup :: MonadJSM m => JSM.String -> Object -> m (Maybe JSVal)
    • toMaybe :: MonadJSM m => JSVal -> m (Maybe JSVal)
    • doNothing :: JSCallAsFunction
  • JSDOM.Extras.WaitForJS

    • getGlobalJS :: MonadJSM m => Text -> m (Maybe JSVal)
    • waitForGlobalJS :: MonadJSM m => Text -> m JSVal
    • withGlobalJS :: MonadJSM m => Text -> (JSVal -> m a) -> m a