93 lines
2.1 KiB
JavaScript
93 lines
2.1 KiB
JavaScript
/////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin 4 - PostgreSQL Tools
|
|
//
|
|
// Copyright (C) 2013 - 2025, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
import React from 'react';
|
|
|
|
/////////
|
|
//
|
|
// A class to handle the ScheamState subscription for a control to avoid
|
|
// rendering multiple times.
|
|
//
|
|
class SubscriberManager {
|
|
|
|
constructor(refreshKeyCallback) {
|
|
this.mounted = true;
|
|
this.callback = refreshKeyCallback;
|
|
this.unsubscribers = new Set();
|
|
this._id = Date.now();
|
|
}
|
|
|
|
add(schemaState, accessPath, kind, callback) {
|
|
if (!schemaState) return;
|
|
|
|
callback = callback || (() => this.signal());
|
|
|
|
return this._add(schemaState.subscribe(accessPath, callback, kind));
|
|
}
|
|
|
|
_add(unsubscriber) {
|
|
if (!unsubscriber) return;
|
|
// Avoid reinsertion of same unsubscriber.
|
|
if (this.unsubscribers.has(unsubscriber)) return;
|
|
this.unsubscribers.add(unsubscriber);
|
|
|
|
return () => this.remove(unsubscriber);
|
|
}
|
|
|
|
remove(unsubscriber) {
|
|
if (!unsubscriber) return;
|
|
if (!this.unsubscribers.has(unsubscriber)) return;
|
|
this.unsubscribers.delete(unsubscriber);
|
|
unsubscriber();
|
|
}
|
|
|
|
signal() {
|
|
// Do nothing - if already work is in progress.
|
|
if (!this.mounted) return;
|
|
this.mounted = false;
|
|
this.release();
|
|
this.callback(Date.now());
|
|
}
|
|
|
|
release () {
|
|
const unsubscribers = this.unsubscribers;
|
|
this.unsubscribers = new Set();
|
|
this.mounted = true;
|
|
|
|
setTimeout(() => {
|
|
Set.prototype.forEach.call(
|
|
unsubscribers, (unsubscriber) => unsubscriber()
|
|
);
|
|
}, 0);
|
|
}
|
|
|
|
mount() {
|
|
this.mounted = true;
|
|
}
|
|
}
|
|
|
|
export function useSchemaStateSubscriber(refreshKeyCallback) {
|
|
const subscriberManager = React.useRef(null);
|
|
|
|
React.useEffect(() => {
|
|
if (!subscriberManager.current) return;
|
|
|
|
return () => {
|
|
subscriberManager.current?.release();
|
|
};
|
|
}, []);
|
|
|
|
if (!subscriberManager.current)
|
|
subscriberManager.current = new SubscriberManager(refreshKeyCallback);
|
|
else
|
|
subscriberManager.current.mount();
|
|
|
|
return subscriberManager;
|
|
}
|