Skip to content

Instantly share code, notes, and snippets.

@saman-taghavi
Created June 24, 2023 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saman-taghavi/e47ab2f21ae7cf364d548673b74dbc1a to your computer and use it in GitHub Desktop.
Save saman-taghavi/e47ab2f21ae7cf364d548673b74dbc1a to your computer and use it in GitHub Desktop.
atomWithBroadCast.ts
import { atom } from "jotai";
const strAtom = atom(""); // primitive string atom
export function atomWithBroadcast<Value>(key: string, initialValue: Value) {
const channel = new BroadcastChannel(key);
const baseAtom = atom(initialValue);
const listeners = new Set<(event: MessageEvent<any>) => void>();
const broadcastAtom = atom<
Value,
[{ fromOnMessage: boolean; value: Value }],
void
>(
(get) => get(baseAtom),
(get, set, update) => {
if (!update.fromOnMessage) {
channel.postMessage(update.value);
}
set(baseAtom, update.value);
}
);
broadcastAtom.onMount = (setAtom) => {
const listener = (event: MessageEvent<any>) => {
setAtom({ fromOnMessage: true, value: event.data });
};
listeners.add(listener);
channel.onmessage = (event) => {
listeners.forEach((l) => l(event));
};
return () => {
channel.close();
listeners.delete(listener);
};
};
const returnedAtom = atom<Value, [Value], void>(
(get) => get(broadcastAtom),
(get, set, update) => {
set(broadcastAtom, { fromOnMessage: false, value: update });
}
);
return returnedAtom;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment