@stackoverfloweth/vue-compositions
Version:
A collection of reusable vue compositions.
179 lines • 6.09 kB
JavaScript
import { getCurrentInstance, nextTick } from 'vue';
function throttle(fn, wait) {
let isThrottled = false;
let invokedDuringThrottle = false;
function wrapper() {
if (isThrottled) {
invokedDuringThrottle = true;
return;
}
isThrottled = true;
fn.apply(this);
setTimeout(() => {
isThrottled = false;
if (invokedDuringThrottle) {
wrapper.apply(this);
invokedDuringThrottle = false;
}
}, wait);
}
return wrapper;
}
const SUBSCRIPTIONS_INSPECTOR_ID = 'prefect-vue-compositions-subscriptions';
const SUBSCRIPTIONS_TIMELINE_LAYER_ID = 'prefect-vue-compositions-subscriptions';
export const SUBSCRIPTION_DEVTOOLS_SETTINGS = {
// timelineColor: {
// label: 'Timeline Color',
// type: 'choice',
// defaultValue: 0xFF69B4,
// options: [
// { value: 0x4fc08d, label: 'Vue Green' },
// { value: 0x175cd3, label: 'Prefect Blue' },
// { value: 0xFF69B4, label: 'Hot' }
// ],
// component: 'button-group'
// }
};
const channelNodes = new Map();
const subscribedComponents = new Map();
let API = null;
export function init(api) {
API = api;
api.addInspector({
id: SUBSCRIPTIONS_INSPECTOR_ID,
label: 'Subscriptions',
icon: 'subscriptions',
treeFilterPlaceholder: 'Search subscriptions',
});
api.on.getInspectorTree((payload) => {
if (payload.inspectorId === SUBSCRIPTIONS_INSPECTOR_ID) {
payload.rootNodes = [];
// 'i' flag for case-insensitive search
const regex = new RegExp(payload.filter, 'i');
for (const { node } of channelNodes.values()) {
if (payload.filter && !regex.test(node.label)) {
continue;
}
payload.rootNodes.push(node);
}
}
});
api.on.getInspectorState(async (payload) => {
if (payload.inspectorId === SUBSCRIPTIONS_INSPECTOR_ID) {
payload.state = await getCustomInspectorState(payload.nodeId);
}
});
// Timeline Layer
api.addTimelineLayer({
id: SUBSCRIPTIONS_TIMELINE_LAYER_ID,
label: 'Subscriptions',
color: 0x175cd3,
});
// api.on.setPluginSettings((payload, context) => {
// })
}
function initialized() {
return API !== null;
}
const refresh = throttle(() => {
setTimeout(async () => {
await nextTick();
API?.sendInspectorState(SUBSCRIPTIONS_INSPECTOR_ID);
API?.sendInspectorTree(SUBSCRIPTIONS_INSPECTOR_ID);
}, 100);
}, 200);
export function addChannel(channel) {
if (!initialized()) {
return;
}
addTimelineEvent({ title: `${channel.actionName} · Channel created`, data: { channel, action: channel.actionName }, groupId: channel.signature });
channelNodes.set(channel.signature, { node: mapChannelToInspectorNode(channel), channel });
refresh();
}
export function updateChannel(channel, event) {
if (!initialized()) {
return;
}
channelNodes.set(channel.signature, { node: mapChannelToInspectorNode(channel), channel });
addTimelineEvent(event);
refresh();
}
export function removeChannel(channel) {
if (!initialized()) {
return;
}
addTimelineEvent({ title: `${channel.actionName} · Channel removed`, data: { channel, action: channel.actionName }, groupId: channel.signature });
channelNodes.delete(channel.signature);
refresh();
}
export function registerChannelSubscription(channel, subscriptionId) {
if (!initialized()) {
return;
}
addTimelineEvent({ title: `${channel.actionName} · Subscription created`, data: { channel, action: channel.actionName, subscriptionId }, groupId: channel.signature });
const channelSubscriptions = subscribedComponents.get(channel.signature) ?? new Map();
const vm = getCurrentInstance();
channelSubscriptions.set(subscriptionId, vm);
subscribedComponents.set(channel.signature, channelSubscriptions);
refresh();
}
export function removeChannelSubscription(channel, subscriptionId) {
if (!initialized()) {
return;
}
addTimelineEvent({ title: `${channel.actionName} · Subscription removed`, data: { channel, action: channel.actionName, subscriptionId }, groupId: channel.signature });
const channelSubscriptions = subscribedComponents.get(channel.signature);
if (!channelSubscriptions) {
return;
}
channelSubscriptions.delete(subscriptionId);
refresh();
}
async function getCustomInspectorState(nodeId) {
const { channel } = channelNodes.get(nodeId) ?? {};
if (!channel) {
return { 'Error': [{ key: 'message', value: 'Channel not found.' }], 'State': [], 'Subscribed Components': [] };
}
const subscriptions = subscribedComponents.get(channel.signature) ?? new Map();
return {
'State': [
{
key: 'channel',
value: channel,
},
],
'Subscribed Components': await Promise.all([...subscriptions.entries()].map(async ([id, vm]) => {
let componentName = vm ? await API?.getComponentName(vm) : null;
if (!componentName) {
componentName = vm === null ? '﹖ Unknown component' : "🔎 Couldn't resolve component name";
}
return {
key: String(id),
value: componentName,
};
})),
};
}
function addTimelineEvent(event) {
API?.addTimelineEvent({
layerId: SUBSCRIPTIONS_TIMELINE_LAYER_ID,
event: {
...event,
time: API.now(),
},
});
}
function mapChannelToInspectorNode(channel) {
return {
id: channel.signature,
label: `${channel.actionName} ${channel.signature}`,
tags: [
{
label: 'channel',
textColor: 0xffffff,
backgroundColor: 0x175cd3,
},
],
};
}
//# sourceMappingURL=useSubscriptionDevtools.js.map