Skip to content

Instantly share code, notes, and snippets.

@ZouYouShun
Last active May 2, 2024 07:23
Show Gist options
  • Save ZouYouShun/1600af64d13728f3775dd728d6ad1460 to your computer and use it in GitHub Desktop.
Save ZouYouShun/1600af64d13728f3775dd728d6ad1460 to your computer and use it in GitHub Desktop.
createExternalExecController
import {
filter,
firstValueFrom,
fromEvent,
map,
merge,
share,
tap,
timer,
} from 'rxjs';
/**
* Creates an external execution controller.
*
* @example
* ```tsx
* const execController = createExternalExecController("my-channel", (value) => {
* console.log(value);
* });
*
* execController.isExist().then((isExist) => {
* if (!isExist) {
* execController.exec("Hello, world!"); // will exec in external window that receive the message
* }
* });
* ```
*
* @param channelName - The name of the broadcast channel.
* @param exec - A function that handles the execution of a value.
* @returns An object with methods and properties related to the external execution controller.
*/
export function createExternalExecController(
channelName: string,
exec: (value: string | object) => void,
) {
const channel = new BroadcastChannel(channelName);
const events = {
exec: 'exec',
isExist: 'isExist',
isExistResponse: 'isExistResponse',
};
const obs = fromEvent<
MessageEvent<{ type: keyof typeof events; value: string | object }>
>(channel, 'message').pipe(
map((event) => event.data),
tap(({ type, value }) => {
switch (type) {
case 'isExist':
channel.postMessage({ type: events.isExistResponse });
break;
case 'exec':
exec(value);
break;
default:
break;
}
}),
share(),
);
obs.subscribe();
return {
channel,
events,
exec: (value?: string | object) => {
channel.postMessage({ type: events.exec, value });
},
isExist: async () => {
channel.postMessage({ type: events.isExist });
const result = await firstValueFrom(
merge(
timer(1000).pipe(map(() => false)),
obs.pipe(
filter((x) => x.type === events.isExistResponse),
map(() => true),
),
),
);
return result;
},
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment