miso-1.13.0.0: src/Miso/Subscription/Cookie.hs
-----------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
-----------------------------------------------------------------------------
-- |
-- Module : Miso.Subscription.Cookie
-- Copyright : (C) 2016-2026 David M. Johnson
-- License : BSD3-style (see the file LICENSE)
-- Maintainer : David M. Johnson <code@dmj.io>
-- Stability : experimental
-- Portability : non-portable
--
-- = Overview
--
-- "Miso.Subscription.Cookie" provides 'cookieChangeSub', an optional
-- subscription that delivers
-- <https://developer.mozilla.org/en-US/docs/Web/API/CookieStore/change_event cookieStore change>
-- events into the update loop. Each event carries the list of cookies that
-- were added\/updated and the list that were deleted since the last event.
--
-- The subscription is optional — applications that only need one-shot reads
-- and writes can use 'Miso.Cookie.cookieGet', 'Miso.Cookie.cookieSet', and
-- 'Miso.Cookie.cookieDelete' directly without registering a subscription.
--
-- = Quick start
--
-- @
-- import "Miso"
-- import "Miso.Subscription.Cookie"
-- import "Miso.Cookie" ('CookieChangeEvent' (..))
--
-- data Action = CookiesChanged 'CookieChangeEvent'
--
-- subs :: ['Miso.Effect.Sub' Action]
-- subs = [ 'cookieChangeSub' CookiesChanged ]
--
-- update :: Action -> 'Miso.Effect.Effect' p props Model Action
-- update (CookiesChanged ev) =
-- 'Miso.Effect.io_' (consoleLog (ms (show (@cookiesChanged@ ev))))
-- @
--
-- = Availability
--
-- The CookieStore API requires a
-- <https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts secure context>
-- (HTTPS or @localhost@) and is not yet supported in all browsers. The
-- subscription silently does nothing when @cookieStore@ is unavailable.
--
-- = See also
--
-- * "Miso.Cookie" — 'Miso.Cookie.cookieGet', 'Miso.Cookie.cookieSet',
-- 'Miso.Cookie.cookieDelete', 'Miso.Cookie.cookieGetAll'
-- * "Miso.Subscription.Util" — 'Miso.Subscription.Util.createSub' used internally
-- * "Miso.Subscription" — re-export hub
-----------------------------------------------------------------------------
module Miso.Subscription.Cookie
( -- ** Subscriptions
cookieChangeSub
) where
-----------------------------------------------------------------------------
import Miso.Cookie (CookieChangeEvent)
import Miso.DSL (fromJSVal)
import Miso.Effect (Sub)
import Miso.Subscription.Util (createSub)
import qualified Miso.FFI.Internal as FFI
-----------------------------------------------------------------------------
-- | Returns a 'Sub' that fires an action on every
-- <https://developer.mozilla.org/en-US/docs/Web/API/CookieStore/change_event cookieStore change>
-- event, carrying the decoded 'CookieChangeEvent' (changed and deleted
-- cookie lists).
--
-- The subscription is self-contained: it registers the listener on mount
-- and removes it on unmount via 'Miso.Subscription.Util.createSub'.
--
-- <https://developer.mozilla.org/en-US/docs/Web/API/CookieStore/change_event>
--
-- @since 1.13.0.0
cookieChangeSub
:: (CookieChangeEvent -> action)
-- ^ Callback: receives the change event on every cookie modification
-> Sub model action
cookieChangeSub f sink = createSub acquire release sink
where
acquire = FFI.cookieStoreAddEventListener $ \ev ->
fromJSVal ev >>= mapM_ (sink . f)
release = FFI.cookieStoreRemoveEventListener
-----------------------------------------------------------------------------