mirror of
https://github.com/robonen/tools.git
synced 2026-03-21 03:14:43 +00:00
feat(web/vue): update version to 0.0.13 and add useTabLeader composable with tests
This commit is contained in:
@@ -1,4 +1,15 @@
|
||||
import { customRef, onScopeDispose } from 'vue';
|
||||
import { customRef, ref } from 'vue';
|
||||
import type { Ref } from 'vue';
|
||||
import { defaultWindow } from '@/types';
|
||||
import { tryOnScopeDispose } from '@/composables/lifecycle/tryOnScopeDispose';
|
||||
|
||||
export interface BroadcastedRefOptions {
|
||||
/**
|
||||
* Immediately broadcast the initial value to other tabs on creation
|
||||
* @default false
|
||||
*/
|
||||
immediate?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name broadcastedRef
|
||||
@@ -7,35 +18,51 @@ import { customRef, onScopeDispose } from 'vue';
|
||||
*
|
||||
* @param {string} key The channel key to use for broadcasting
|
||||
* @param {T} initialValue The initial value of the ref
|
||||
* @param {BroadcastedRefOptions} [options={}] Options
|
||||
* @returns {Ref<T>} A custom ref that broadcasts value changes across tabs
|
||||
*
|
||||
* @example
|
||||
* const count = broadcastedRef('counter', 0);
|
||||
*
|
||||
* @since 0.0.1
|
||||
* @example
|
||||
* const state = broadcastedRef('payment-status', { status: 'pending' });
|
||||
*
|
||||
* @since 0.0.13
|
||||
*/
|
||||
export function broadcastedRef<T>(key: string, initialValue: T) {
|
||||
export function broadcastedRef<T>(key: string, initialValue: T, options: BroadcastedRefOptions = {}): Ref<T> {
|
||||
const { immediate = false } = options;
|
||||
|
||||
if (!defaultWindow || typeof BroadcastChannel === 'undefined') {
|
||||
return ref(initialValue) as Ref<T>;
|
||||
}
|
||||
|
||||
const channel = new BroadcastChannel(key);
|
||||
let value = initialValue;
|
||||
|
||||
onScopeDispose(channel.close);
|
||||
|
||||
return customRef<T>((track, trigger) => {
|
||||
channel.onmessage = (event) => {
|
||||
track();
|
||||
return event.data;
|
||||
const data = customRef<T>((track, trigger) => {
|
||||
channel.onmessage = (event: MessageEvent<T>) => {
|
||||
value = event.data;
|
||||
trigger();
|
||||
};
|
||||
|
||||
channel.postMessage(initialValue);
|
||||
|
||||
return {
|
||||
get() {
|
||||
return initialValue;
|
||||
track();
|
||||
return value;
|
||||
},
|
||||
set(newValue: T) {
|
||||
initialValue = newValue;
|
||||
value = newValue;
|
||||
channel.postMessage(newValue);
|
||||
trigger();
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
if (immediate) {
|
||||
channel.postMessage(initialValue);
|
||||
}
|
||||
|
||||
tryOnScopeDispose(() => channel.close());
|
||||
|
||||
return data;
|
||||
}
|
||||
Reference in New Issue
Block a user