Skip to content

Broadcast Channel

Reactive Broadcast Channel.

๐ŸŽฌ Usage

<script>
    import {broadcast_channel} from "@sveu/browser"

    const {data, post, error} = broadcast_channel()


    $: if ($data) alert($data)

    let value = "HI"
</script>

<h1>Open new Tab, and start a broadcast :)</h1>
<input type="text" bind:value />

<button on:click="{() => post(value)}">Post</button>

๐Ÿ‘ฉโ€๐Ÿ’ปAPI

๐Ÿ™ˆ Options

Name Description Type Default
name The name of the broadcast channel string default

โ†ฉ๏ธ Returns

Name Description Type
supported Is the browser support broadcast channel Readable<boolean>
closed Is the broadcast channel closed Readable<boolean>
data The data from the broadcast channel Readable<unknown>
error The error from the broadcast channel Readable<Event | null>
close Close the broadcast channel () => void
post Send data to the broadcast channel (data: unknown) => void
channel The broadcast channel Readable<BroadcastChannel | undefined>

๐Ÿงช Playground

Source Code ๐Ÿ‘€

Source Code
import {
    browser,
    on_destroy,
    to_readable,
    to_writable,
    unstore,
} from "@sveu/shared"

import { on } from "../event_listener"
import { support } from "../support"
import type { BroadcastChannelOptions } from "../utils"

/**
 * Reactive BroadcastChannel
 *
 * @param options - The options for the BroadcastChannel.
 * - `name` - The name of the channel. default: `default`
 *
 * @returns
 * - `supported` - Is the BroadcastChannel supported.
 * - `channel` - The BroadcastChannel instance.
 * - `data` - The data from the channel.
 * - `post` - Send data to the channel.
 * - `close` - Close the channel.
 * - `error` - The error from the channel.
 * - `closed` - Is the channel closed.
 */
export function broadcast_channel(options: BroadcastChannelOptions = {}) {
    const { name = "default" } = options

    const supported = support("BroadcastChannel", "window")

    const closed = to_writable(false)

    const channel = to_writable<BroadcastChannel | undefined>(undefined)

    const data = to_writable<unknown>(undefined)

    const error = to_writable<Event | null>(null)

    /**
     * Send data to the channel.
     *
     * @param data - The data to send to the channel.
     */
    function post(data: unknown) {
        unstore(channel)?.postMessage(data)
    }

    /** Close the channel. */
    function close() {
        unstore(channel)?.close()
        closed.set(true)
    }

    if (unstore(supported) && browser) {
        error.set(null)

        channel.set(new BroadcastChannel(name))

        on(
            unstore(channel),
            "message",
            (event: MessageEvent) => {
                data.set(event.data)
            },
            { passive: true }
        )

        on(
            unstore(channel),
            "messageerror",
            (event: Event) => {
                error.set(event)
            },
            { passive: true }
        )

        on(
            unstore(channel),
            "close",
            () => {
                closed.set(true)
            },
            { passive: true }
        )
    }

    on_destroy(close)

    return {
        channel: to_readable(channel),
        closed: to_readable(closed),
        data: to_readable(data),
        error: to_readable(error),
        supported,
        close,
        post,
    }
}

Last update: 2023-03-09