New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@notifi-network/notifi-graphql

Package Overview
Dependencies
Maintainers
0
Versions
356
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@notifi-network/notifi-graphql - npm Package Compare versions

Comparing version 3.0.2-alpha.11 to 3.1.0

0

lib/gql/mutations/beginLogInWithWeb3.gql.ts

@@ -0,0 +0,0 @@ import { gql } from 'graphql-request';

@@ -0,0 +0,0 @@ import { gql } from 'graphql-request';

@@ -0,0 +0,0 @@ import { gql } from 'graphql-request';

11

lib/gql/subscriptions/stateChanged.gql.ts

@@ -6,3 +6,12 @@ import { gql } from 'graphql-request';

stateChanged {
__typename
... on TargetStateChangedEvent {
__typename
targetId
targetType
timestamp
}
... on NotificationHistoryStateChangedEvent {
__typename
timestamp
}
}

@@ -9,0 +18,0 @@ }

@@ -0,0 +0,0 @@ import { ActiveAlertFragment } from '../fragments/ActiveAlertFragment.gql';

67

lib/NotifiEventEmitter.ts

@@ -1,2 +0,3 @@

import { Client as WebSocketClient } from 'graphql-ws';
import { Subscription } from 'relay-runtime';
import {

@@ -7,22 +8,4 @@ StateChangedEvent,

/** IMPORTANT: the guidelines to remove the event listener:
* 1. For status events (NotifiWebSocketStatusEvents or NotifiSubscriptionStatusEvents), calling removeEventListener will remove the listener.
* 2. For graphql subscription events (NotifiSubscriptionEvents), calling removeEventListener will not unsubscribe the subscription. additionally, you need to call subscription.unsubscribe() to remove the subscription.
*/
export type NotifiEmitterEvents = NotifiWebSocketStatusEvents &
NotifiSubscriptionEvents &
NotifiSubscriptionStatusEvents;
export type NotifiEmitterEvents = NotifiSubscriptionEvents;
export type NotifiWebSocketStatusEvents = {
wsConnecting: [];
wsConnected: [WebSocketClient];
wsClosed: [unknown]; // ⬅ The argument is actually the websocket `CloseEvent`, but to avoid bundling DOM typings because the client can run in Node env too, you should assert the websocket type during implementation. https://the-guild.dev/graphql/ws/docs/modules/client#eventclosedlistener
wsError: [Error];
};
export type NotifiSubscriptionStatusEvents = {
gqlSubscriptionError: [Error];
gqlComplete: [];
};
export type NotifiSubscriptionEvents = {

@@ -33,30 +16,44 @@ tenantActiveAlertChanged: [TenantActiveAlertChangeEvent];

export type EventCallback<
export type ListenerPayload<
T extends Record<string, any[]>,
K extends keyof T,
> = (...args: T[K]) => void;
> = {
callback: (...args: T[K]) => void;
subscription: Subscription;
};
export class NotifiEventEmitter<T extends Record<string, Array<any>>> {
private listeners: { [K in keyof T]?: Array<EventCallback<T, K>> } = {};
private listeners: {
[K in keyof T]?: Record<string, ListenerPayload<T, K>>;
} = {};
on<K extends keyof T>(event: K, listener: EventCallback<T, K>): void {
on<K extends keyof T>(
event: K,
listener: ListenerPayload<T, K>,
id: string,
): void {
if (!this.listeners[event]) {
this.listeners[event] = [];
this.listeners[event] = {};
}
this.listeners[event]!.push(listener);
(this.listeners[event] as Record<string, ListenerPayload<T, K>>)[id] = // ⬅ Workaround for TS limitation (not able to infer that this.listeners[event] is defined)
listener;
}
off<K extends keyof T>(event: K, listener: EventCallback<T, K>): void {
if (!this.listeners[event]) return;
this.listeners[event] = this.listeners[event]!.filter(
(l) => l !== listener,
);
off<K extends keyof T>(event: K, id: string): void {
if (!this.listeners[event]?.[id]) return;
(this.listeners[event] as Record<string, ListenerPayload<T, K>>)[ // ⬅ Workaround for TS limitation (not able to infer that this.listeners[event] is defined)
id
].subscription
.unsubscribe();
delete (this.listeners[event] as Record<string, ListenerPayload<T, K>>)[id]; // ⬅ Workaround for TS limitation (not able to infer that this.listeners[event] is defined)
}
emit<K extends keyof T>(event: K, ...args: T[K]): void {
if (!this.listeners[event]) return;
for (const listener of this.listeners[event]!) {
listener(...args);
emit<K extends keyof T>(event: K, id: string, ...args: T[K]): void {
if (!this.listeners[event]?.[id]) return;
if (this.listeners[event]?.[id]) {
(this.listeners[event] as Record<string, ListenerPayload<T, K>>)[id] // ⬅ Workaround for TS limitation (not able to infer that this.listeners[event] is defined)
.callback(...args);
}
}
}
import { GraphQLClient } from 'graphql-request';
import { Subscription } from 'relay-runtime';
import { v4 as uuid } from 'uuid';
import { version } from '../package.json';
import { NotifiEmitterEvents } from './NotifiEventEmitter';
import { NotifiSubscriptionService } from './NotifiSubscriptionService';
import { stateChangedSubscriptionQuery } from './gql';
import * as Generated from './gql/generated';
import { getSdk } from './gql/generated';
import type * as Operations from './operations';
import { stateChangedSubscriptionQuery } from './gql';
import { NotifiEmitterEvents } from './NotifiEventEmitter';
import { Subscription } from 'relay-runtime';

@@ -456,8 +456,8 @@ export class NotifiService

*/
async subscribeNotificationHistoryStateChanged(
subscribeNotificationHistoryStateChanged(
onMessageReceived: (data: any) => void | undefined,
onError?: (data: any) => void | undefined,
onComplete?: () => void | undefined,
): Promise<void> {
this._notifiSubService.subscribe(
): Subscription | null {
return this._notifiSubService.subscribe(
this._jwt,

@@ -475,18 +475,24 @@ stateChangedSubscriptionQuery,

/**
* @returns {string} - The id of the event listener (used to remove the event listener)
*/
addEventListener<T extends keyof NotifiEmitterEvents>(
event: T,
callBack: (...args: NotifiEmitterEvents[T]) => void,
): Subscription | null {
return this._notifiSubService.addEventListener(event, callBack);
onError?: (error: unknown) => void,
onComplete?: () => void,
): string {
return this._notifiSubService.addEventListener(
event,
callBack,
onError,
onComplete,
);
}
/**
* @important To remove event listener, check the README.md of `notifi-node` or `notifi-frontend-client` package for more details.
* - `notifi-node`: https://github.com/notifi-network/notifi-sdk-ts/tree/main/packages/notifi-node
* - `notifi-frontend-client`: https://github.com/notifi-network/notifi-sdk-ts/tree/main/packages/notifi-frontend-client
*/
removeEventListener<T extends keyof NotifiEmitterEvents>(
event: T,
callBack: (...args: NotifiEmitterEvents[T]) => void,
id: string,
) {
return this._notifiSubService.removeEventListener(event, callBack);
return this._notifiSubService.removeEventListener(event, id);
}

@@ -493,0 +499,0 @@

import {
SubscribePayload,
Client as WebSocketClient,
createClient,
Client as WebSocketClient,
SubscribePayload,
} from 'graphql-ws';
import { Observable, Subscription } from 'relay-runtime';
import {
NotifiEmitterEvents,
NotifiEventEmitter,
NotifiEmitterEvents,
NotifiSubscriptionEvents,

@@ -15,6 +16,15 @@ } from './NotifiEventEmitter';

type SubscriptionQuery =
export type SubscriptionQuery =
| typeof stateChangedSubscriptionQuery
| typeof tenantActiveAlertChangedSubscriptionQuery;
export type SubscribeInputs = {
subscriptionQuery: SubscriptionQuery;
id: string;
onError?: (error: unknown) => void;
onComplete?: () => void;
};
type _Subscribe = (input: SubscribeInputs) => Subscription | null;
/**

@@ -38,84 +48,46 @@ * @param webSocketImpl - A custom WebSocket implementation to use instead of the one provided by the global scope. Mostly useful for when using the client outside of the browser environment.

/**
* @deprecated Should not directly manipulate the websocket client. Instead use the returned subscription object to manage the subscription. ex. subscription.unsubscribe()
* @returns {string} - The id of the event listener (used to remove the event listener)
*/
disposeClient = () => {
if (this._wsClient) {
this._jwt = undefined;
this._wsClient.terminate();
this._wsClient.dispose();
}
};
/**
* @deprecated Use addEventListener instead
*/
subscribe = (
jwt: string | undefined,
subscriptionQuery: string,
onMessageReceived: (data: any) => void | undefined,
onError?: (data: any) => void | undefined,
onComplete?: () => void | undefined,
) => {
this._jwt = jwt;
if (!this._wsClient) {
this._initializeClient();
}
if (!this._wsClient) return null;
const observable = this._toObservable(this._wsClient, {
query: subscriptionQuery,
extensions: {
type: 'start',
},
});
const subscription = observable.subscribe({
next: (data) => {
if (onMessageReceived) {
onMessageReceived(data);
}
},
error: (error: unknown) => {
if (onError && error instanceof Error) {
onError(error);
}
},
complete: () => {
console.log('Subscription complete');
if (onComplete) {
onComplete();
}
},
});
return subscription;
};
/**
* @important for removing the event listener, check the guidelines in the NotifiEventEmitter (notifi-graphql/lib/NotifiEventEmitter.ts) class. https://github.com/notifi-network/notifi-sdk-ts/tree/main/packages/notifi-graphql/lib
*/
addEventListener = <T extends keyof NotifiEmitterEvents>(
event: T,
callBack: (...args: NotifiEmitterEvents[T]) => void,
) => {
this.eventEmitter.on(event, callBack);
callback: (...args: NotifiEmitterEvents[T]) => void,
onError?: (error: unknown) => void,
onComplete?: () => void,
): string => {
const id = Math.random().toString(36).slice(2, 11); // ⬅ Generate a random id for the listener
const subscribeInputs: SubscribeInputs = {
subscriptionQuery: '' as SubscriptionQuery, // ⬅ Placeholder (empty string intentionally)
id,
onError,
onComplete,
};
switch (event) {
case 'stateChanged':
return this._subscribe(stateChangedSubscriptionQuery);
subscribeInputs.subscriptionQuery = stateChangedSubscriptionQuery;
break;
case 'tenantActiveAlertChanged':
return this._subscribe(tenantActiveAlertChangedSubscriptionQuery);
subscribeInputs.subscriptionQuery =
tenantActiveAlertChangedSubscriptionQuery;
break;
default:
return null;
throw new Error('Unknown event');
}
const subscription = this._subscribe(subscribeInputs);
if (!subscription)
throw new Error(
'NotifiSubscriptionService.addEventListener: Subscription failed',
);
this.eventEmitter.on(event, { callback, subscription }, id);
return id;
};
/**
* @important To remove event listener, check the README.md of `notifi-node` or `notifi-frontend-client` package for more details.
* - `notifi-node`: https://github.com/notifi-network/notifi-sdk-ts/tree/main/packages/notifi-node
* - `notifi-frontend-client`: https://github.com/notifi-network/notifi-sdk-ts/tree/main/packages/notifi-frontend-client
*/
removeEventListener = <T extends keyof NotifiEmitterEvents>(
event: T,
callBack: (...args: NotifiEmitterEvents[T]) => void,
id: string,
) => {
return this.eventEmitter.off(event, callBack);
return this.eventEmitter.off(event, id);
};

@@ -126,5 +98,8 @@

*/
private _subscribe = (
subscriptionQuery: SubscriptionQuery,
): Subscription | null => {
private _subscribe: _Subscribe = ({
subscriptionQuery,
id,
onError,
onComplete,
}) => {
if (!this._wsClient) {

@@ -136,4 +111,2 @@ this._initializeClient();

console.log('Subscribing, JWT & wsClient are set'); // TODO: Remove before merge
const observable = this._toObservable(this._wsClient, {

@@ -154,3 +127,3 @@ query: subscriptionQuery,

}
this.eventEmitter.emit('stateChanged', stateChangedData);
this.eventEmitter.emit('stateChanged', id, stateChangedData);
break;

@@ -167,2 +140,3 @@ case tenantActiveAlertChangedSubscriptionQuery:

'tenantActiveAlertChanged',
id,
tenantActiveAlertChangedData,

@@ -175,11 +149,4 @@ );

},
error: (error: unknown) => {
this.eventEmitter.emit(
'gqlSubscriptionError',
error instanceof Error
? error
: new Error('Unknown gql subscription error'),
);
},
complete: () => this.eventEmitter.emit('gqlComplete'),
error: onError,
complete: onComplete,
});

@@ -205,2 +172,7 @@

private _initializeClient = () => {
if (!this._jwt)
throw new Error(
'NotifiSubscriptionService._initializeClient: Missing JWT',
);
this._wsClient = createClient({

@@ -215,23 +187,85 @@ url: this.wsurl,

this._wsClient.on('connecting', () => {
this.eventEmitter.emit('wsConnecting');
});
/** ⬇ Uncomment to monitor websocket behavior (debugging purpose) */
// this._wsClient.on('connecting', () => {
// console.info(
// 'NotifiSubscriptionService._initializeClient: Connecting to ws',
// );
// });
this._wsClient.on('connected', () => {
this.eventEmitter.emit('wsConnected', this._wsClient!);
// this._wsClient.on('connected', () => {
// console.info(
// 'NotifiSubscriptionService._initializeClient: Connected to ws',
// );
// });
// this._wsClient.on('closed', (event) => {
// console.info(
// 'NotifiSubscriptionService._initializeClient: Closed ws',
// event,
// );
// });
// this._wsClient.on('error', (error) => {
// console.error(
// 'NotifiSubscriptionService._initializeClient: Websocket Error:',
// error,
// );
// });
};
/* ⬇⬇⬇⬇⬇ Deprecated methods ⬇⬇⬇⬇⬇⬇ */
/**
* @deprecated Should not directly manipulate the websocket client. Instead use the returned subscription object to manage the subscription. ex. subscription.unsubscribe()
*/
disposeClient = () => {
if (this._wsClient) {
this._jwt = undefined;
this._wsClient.terminate();
this._wsClient.dispose();
}
};
/**
* @deprecated Use addEventListener instead
*/
subscribe = (
jwt: string | undefined,
subscriptionQuery: string,
onMessageReceived: (data: any) => void | undefined,
onError?: (data: any) => void | undefined,
onComplete?: () => void | undefined,
) => {
this._jwt = jwt;
if (!this._wsClient) {
this._initializeClient();
}
if (!this._wsClient) return null;
const observable = this._toObservable(this._wsClient, {
query: subscriptionQuery,
extensions: {
type: 'start',
},
});
this._wsClient.on('closed', (event) => {
this.eventEmitter.emit('wsClosed', event);
const subscription = observable.subscribe({
next: (data) => {
if (onMessageReceived) {
onMessageReceived(data);
}
},
error: (error: unknown) => {
if (onError && error instanceof Error) {
onError(error);
}
},
complete: () => {
if (onComplete) {
onComplete();
}
},
});
this._wsClient.on('error', (error) => {
if (error instanceof Error /*⬅ Client (browser) side error*/) {
return this.eventEmitter.emit('wsError', error);
}
this.eventEmitter.emit('wsError', {
...(error as Error),
message: 'NotifiEventEmitter: Server side or unknown error',
});
});
return subscription;
};

@@ -238,0 +272,0 @@ }

{
"name": "@notifi-network/notifi-graphql",
"version": "3.0.2-alpha.11+1cedd3be",
"version": "3.1.0",
"description": "The GraphQL API for Notifi",

@@ -49,3 +49,3 @@ "main": "./dist/index.js",

},
"gitHead": "1cedd3be1f08ba8f9e318b65ce9d8b6a36f02107"
"gitHead": "23052e48ac17f22c51635ea827d6f1a107352ec5"
}
{
"extends": "../../tsconfig.json",
}

@@ -0,0 +0,0 @@ {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc