import * as React from 'react';
import { z } from 'zod/v4';
const SESSION_STATE_CHANNEL_NAME = 'dara-session-state';
const SessionStateMessageSchema = z.discriminatedUnion('type', [
    z.object({
        type: z.literal('session_id'),
        value: z.string().nullable(),
    }),
    z.object({
        type: z.literal('session_logged_out'),
    }),
]);
const sessionIdSubscribers = new Set();
let sessionIdentifier = null;
const channel = typeof BroadcastChannel !== 'undefined' ? new BroadcastChannel(SESSION_STATE_CHANNEL_NAME) : null;
/**
 * Notify local subscribers about an updated session identifier.
 *
 * @param value current session identifier
 */
function notifySessionIdSubscribers(value) {
    sessionIdSubscribers.forEach((cb) => cb(value));
}
/**
 * Parse a cross-tab session state message.
 *
 * @param value unknown message payload
 */
function parseSessionStateMessage(value) {
    const parsed = SessionStateMessageSchema.safeParse(value);
    if (!parsed.success) {
        return null;
    }
    return parsed.data;
}
/**
 * Update the in-memory session identifier and optionally broadcast it to other tabs.
 *
 * @param value current session identifier
 * @param broadcast whether to emit cross-tab events
 */
function setSessionIdentifierInternal(value, broadcast) {
    if (sessionIdentifier === value) {
        return;
    }
    sessionIdentifier = value;
    notifySessionIdSubscribers(value);
    if (broadcast && channel) {
        channel.postMessage({ type: 'session_id', value });
    }
}
if (channel) {
    channel.addEventListener('message', (event) => {
        const message = parseSessionStateMessage(event.data);
        if (!message) {
            return;
        }
        if (message.type === 'session_logged_out') {
            setSessionIdentifierInternal(null, false);
            return;
        }
        setSessionIdentifierInternal(message.value, false);
    });
}
/**
 * Notify all tabs that the session has been logged out/invalidated.
 */
export function notifySessionLoggedOut() {
    setSessionIdentifierInternal(null, true);
    if (channel) {
        channel.postMessage({ type: 'session_logged_out' });
    }
}
/**
 * Subscribe to session ID changes.
 *
 * @param cb callback to call when the session ID changes
 */
export function onSessionIdChange(cb) {
    sessionIdSubscribers.add(cb);
    return () => {
        sessionIdSubscribers.delete(cb);
    };
}
/**
 * Retrieve the current Dara session ID.
 */
export function getSessionIdentifier() {
    return sessionIdentifier;
}
/**
 * Set the current Dara session ID.
 *
 * @param sessionId session identifier
 */
export function setSessionIdentifier(sessionId) {
    setSessionIdentifierInternal(sessionId, true);
}
/**
 * Helper hook that synchronizes with the current Dara session ID from store.
 */
export function useSessionIdentifier() {
    return React.useSyncExternalStore(onSessionIdChange, getSessionIdentifier);
}
//# sourceMappingURL=session-state.js.map