async-states
Version:
Core of async-states
117 lines (114 loc) • 4.63 kB
JavaScript
import { __DEV__ } from '../../utils.js';
class LibraryDevtools {
// the list of connected devtools clients, can be the npm package,
// the devtools extension, or both for example
listeners = [];
// on connection from a client, we will give it the list of created
// LibraryContexts that hold all instances that are created.
// standalone instances and not stored in context will be gathered too
// in a separate map, and on dispose they will be removed
// this is relevant only on connection to give the full list of current
// instances, after connexion, there is no need because the event
// gives the instance itself and client should ensure instance is retained
standalone = new Set();
contexts = new Set();
constructor() {
this.connect = this.connect.bind(this);
this.emitRun = this.emitRun.bind(this);
this.emitSub = this.emitSub.bind(this);
this.emitUnsub = this.emitUnsub.bind(this);
this.emitUpdate = this.emitUpdate.bind(this);
this.disconnect = this.disconnect.bind(this);
this.startUpdate = this.startUpdate.bind(this);
this.emitDispose = this.emitDispose.bind(this);
this.emitCreation = this.emitCreation.bind(this);
this.emitInstance = this.emitInstance.bind(this);
this.captureContext = this.captureContext.bind(this);
this.releaseContext = this.releaseContext.bind(this);
this.ensureInstanceIsRetained = this.ensureInstanceIsRetained.bind(this);
}
connect(listener) {
this.listeners.push(listener);
// on any connection of any client, we give him the currently retained
// instances. All of them. The list include:
// - Any instance in any non-terminated LibraryContext
// - Any active 'standalone' instance
let instances = [...this.standalone];
for (let context of this.contexts) {
instances.push(...context.getAll());
}
listener.onConnect(instances);
}
disconnect(listener) {
this.listeners = this.listeners.filter((t) => t !== listener);
}
emitCreation(instance) {
if (instance.config.hideFromDevtools)
return;
this.listeners.forEach((listener) => listener.emitCreation(instance));
}
emitDispose(instance) {
if (instance.config.hideFromDevtools)
return;
this.listeners.forEach((listener) => listener.emitDispose(instance));
}
emitInstance(instance) {
if (instance.config.hideFromDevtools)
return;
this.listeners.forEach((listener) => listener.emitInstance(instance));
}
emitRun(instance, cache) {
if (instance.config.hideFromDevtools)
return;
this.listeners.forEach((listener) => listener.emitRun(instance, cache));
}
emitSub(instance, key) {
if (instance.config.hideFromDevtools)
return;
this.ensureInstanceIsRetained(instance);
this.listeners.forEach((listener) => listener.emitSub(instance, key));
}
emitUnsub(instance, key) {
if (instance.config.hideFromDevtools)
return;
// undefined is considered truthy for backward compatibility
// when an unsubscription occurs when not retained by a context, if
// there is no subscription remaining, remove standalone instances
if (instance.config.storeInContext === false &&
Object.keys(instance.subscriptions).length === 0) {
this.standalone.delete(instance);
}
this.listeners.forEach((listener) => listener.emitUnsub(instance, key));
}
startUpdate(instance) {
if (instance.config.hideFromDevtools)
return;
this.listeners.forEach((listener) => listener.startUpdate(instance));
}
emitUpdate(instance, replace) {
if (instance.config.hideFromDevtools)
return;
this.listeners.forEach((listener) => listener.emitUpdate(instance, replace));
}
captureContext(context) {
this.contexts.add(context);
}
onConnect() {
throw new Error("The library devtools agent doesn't have an onConnect.");
}
releaseContext(context) {
this.contexts.delete(context);
}
ensureInstanceIsRetained(instance) {
// undefined is considered truthy for backward compatibility
if (instance.config.storeInContext === false) {
this.standalone.add(instance);
}
}
}
let devtools;
if (__DEV__) {
devtools = new LibraryDevtools();
}
export { devtools };
//# sourceMappingURL=v2.js.map