Skip to content

Commit

Permalink
Allow statusListener to accept node instance instead of id (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
GogoVega authored Feb 23, 2025
1 parent a23fd4e commit 294fccc
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 17 deletions.
43 changes: 27 additions & 16 deletions src/lib/nodes/firebase-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { NodeAPI, NodeStatus } from "node-red";
import { Node, NodeAPI, NodeStatus } from "node-red";
import { Client, FirebaseError, isFirebaseError, ServiceAccount, SignState } from "../firebase/client";
import { Firestore } from "../firebase/firestore";
import { LogCallbackParams, onLog } from "../firebase/logger";
Expand Down Expand Up @@ -90,10 +90,15 @@ export class FirebaseClient {
this.enableConnectionHandler();
}

private addStatusListener(id: string, type: ServiceType) {
this.statusListeners[type].push(id);
// the node does not yet exist at this step => getNode returns null
setImmediate(() => this.setCurrentStatus(id));
private addStatusListener(nodeOrId: Node | string, type: ServiceType) {
this.statusListeners[type].push(nodeOrId);

if (typeof nodeOrId === "string") {
setImmediate(() => this.setCurrentStatus(nodeOrId));
} else {
this.setCurrentStatus(nodeOrId);
}

this.restoreDestroyedConnection();
this.initDatabase(type);
}
Expand Down Expand Up @@ -261,7 +266,6 @@ export class FirebaseClient {
if (this.node.rtdb) return;
// Skip if the client is not initialised
if (!this.node.client?.clientInitialised) return;
// TODO: pas l'idéal (comment gérer une mauvaise URL)
if (this.statusListeners.rtdb.length > 1) return;

try {
Expand Down Expand Up @@ -402,12 +406,12 @@ export class FirebaseClient {
this.node.error(msg || error);
}

private removeStatusListener(id: string, type: ServiceType, done: () => void) {
private removeStatusListener(nodeOrId: Node | string, type: ServiceType, done: () => void) {
try {
const nodes = this.statusListeners[type];

// Remove id from array
const indexToRemove = nodes.indexOf(id);
// Remove node from array
const indexToRemove = nodes.indexOf(nodeOrId);
if (indexToRemove !== -1) nodes.splice(indexToRemove, 1);

done();
Expand All @@ -428,22 +432,26 @@ export class FirebaseClient {
if (this.node.firestore?.offline && this.statusListeners.firestore) this.node.firestore.goOnline();
}

private setCurrentStatus(id: string) {
private setCurrentStatus(nodeOrId: Node | string) {
const { rtdb, firestore, storage } = this.statusListeners;
const node = typeof nodeOrId === "string" ? this.RED.nodes.getNode(nodeOrId) : nodeOrId;

// If the database has no connection state, need to clear the status to avoid keeping the default status
if (
rtdb.includes(id) ||
(firestore.includes(id) && this.node.config.status?.firestore) ||
(storage.includes(id) && this.node.config.status?.storage)
this.globalStatus.text?.startsWith("Error") ||
rtdb.includes(nodeOrId) ||
(firestore.includes(nodeOrId) && this.node.config.status?.firestore) ||
(storage.includes(nodeOrId) && this.node.config.status?.storage)
) {
this.RED.nodes.getNode(id)?.status(this.globalStatus);
node?.status(this.globalStatus);
} else {
this.RED.nodes.getNode(id)?.status({});
node?.status({});
}
}

private updateGlobalStatus(status: ConnectionStatus, text?: string) {
this.node.debug(`Update global status to: ${status} with the message: ${text}`);

// Keep error message if connection message comes
if (this.globalStatus.text?.startsWith("Error") && status !== "error") return;

Expand All @@ -466,6 +474,9 @@ export class FirebaseClient {
nodes.push(...this.statusListeners.storage);
}

nodes.forEach((id) => this.RED.nodes.getNode(id)?.status(newGlobalStatus));
nodes.forEach((nodeOrId) => {
if (typeof nodeOrId === "string") this.RED.nodes.getNode(nodeOrId)?.status(newGlobalStatus);
else nodeOrId.status(newGlobalStatus);
});
}
}
37 changes: 36 additions & 1 deletion src/lib/nodes/types/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export type ConnectionStatus =
| "error"
| "no-network"
| "re-connecting";
export type StatusListeners = Record<ServiceType, Array<string>>;
export type StatusListeners = Record<ServiceType, Array<Node | string>>;

type Credentials = {
apiKey: string;
Expand All @@ -62,21 +62,56 @@ type Credentials = {
export type ConfigNode = Node & {
/**
* Add this node to the Global Configuration Node
* @deprecated
* @param id The node ID
* @param type The Service Type
*/
addStatusListener(id: string, type: ServiceType): void;
/**
* Add this node to the Global Configuration Node
* @param node The node
* @param type The Service Type
*/
addStatusListener(node: Node, type: ServiceType): void;
client?: Client;
clientSignedIn(): Promise<boolean>;
config: Config;
credentials: Credentials;
/**
* Class representing a Cloud Firestore Database.
* Must be instantiated by calling {@link ConfigNode.addStatusListener | addStatusListener}
*/
firestore?: Firestore;
/**
* Remove this node from the Global Configuration Node
* @deprecated
* @param id The node ID
* @param type The Service Type
* @param done Callback
*/
removeStatusListener(id: string, type: ServiceType, done: () => void): void;
/**
* Remove this node from the Global Configuration Node
* @param node The node
* @param type The Service Type
* @param done Callback
*/
removeStatusListener(node: Node, type: ServiceType, done: () => void): void;
/**
* Class representing a Firebase Realtime Database.
* Must be instantiated by calling {@link ConfigNode.addStatusListener | addStatusListener}
*/
rtdb?: RTDB;
/**
* Set the global status to this node
* @deprecated
* @param id The node ID
*/
setCurrentStatus(id: string): void;
/**
* Set the global status to this node
* @param node The node
*/
setCurrentStatus(node: Node): void;
readonly version: string;
};

0 comments on commit 294fccc

Please sign in to comment.