Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

aws-appsync-subscription-link

Package Overview
Dependencies
Maintainers
5
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

aws-appsync-subscription-link - npm Package Compare versions

Comparing version 3.0.11 to 3.1.0

165

__tests__/link/realtime-subscription-handshake-link-test.ts

@@ -5,2 +5,5 @@ import { AUTH_TYPE } from "aws-appsync-auth-link";

import { AppSyncRealTimeSubscriptionHandshakeLink } from '../../src/realtime-subscription-handshake-link';
import { MESSAGE_TYPES } from "../../src/types";
import { v4 as uuid } from "uuid";
jest.mock('uuid', () => ({ v4: jest.fn() }));

@@ -10,3 +13,3 @@ const query = gql`subscription { someSubscription { aField } }`

class myWebSocket implements WebSocket {
binaryType: BinaryType;
binaryType: BinaryType;
bufferedAmount: number;

@@ -364,4 +367,162 @@ extensions: string;

});
})
});
test("Can use a custom keepAliveTimeoutMs", (done) => {
const id = "abcd-efgh-ijkl-mnop";
uuid.mockImplementationOnce(() => id);
expect.assertions(5);
jest.spyOn(Date.prototype, 'toISOString').mockImplementation(jest.fn(() => {
return "2019-11-13T18:47:04.733Z";
}));
AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = jest.fn((url, protocol) => {
expect(url).toBe('wss://apikeytest.testcustomdomain.com/graphql/realtime?header=eyJob3N0IjoiYXBpa2V5dGVzdC50ZXN0Y3VzdG9tZG9tYWluLmNvbSIsIngtYW16LWRhdGUiOiIyMDE5MTExM1QxODQ3MDRaIiwieC1hcGkta2V5IjoieHh4eHgifQ==&payload=e30=');
expect(protocol).toBe('graphql-ws');
const socket = new myWebSocket();
setTimeout(() => {
socket.close = () => {};
socket.onopen.call(socket, (undefined as unknown as Event));
socket.send = (msg: string) => {
const { type } = JSON.parse(msg);
switch (type) {
case MESSAGE_TYPES.GQL_CONNECTION_INIT:
socket.onmessage.call(socket, {
data: JSON.stringify({
type: MESSAGE_TYPES.GQL_CONNECTION_ACK,
payload: {
connectionTimeoutMs: 99999,
},
})
} as MessageEvent);
setTimeout(() => {
socket.onmessage.call(socket, {
data: JSON.stringify({
id,
type: MESSAGE_TYPES.GQL_DATA,
payload: {
data: { something: 123 },
},
})
} as MessageEvent);
}, 100);
break;
}
};
}, 100);
return socket;
});
const link = new AppSyncRealTimeSubscriptionHandshakeLink({
auth: {
type: AUTH_TYPE.API_KEY,
apiKey: 'xxxxx'
},
region: 'us-west-2',
url: 'https://apikeytest.testcustomdomain.com/graphql',
keepAliveTimeoutMs: 123456,
});
expect(link).toBeInstanceOf(AppSyncRealTimeSubscriptionHandshakeLink);
expect((link as any).keepAliveTimeout).toBe(123456);
const sub = execute(link, { query }).subscribe({
error: (err) => {
console.log(JSON.stringify(err));
fail();
},
next: (data) => {
expect((link as any).keepAliveTimeout).toBe(123456);
done();
sub.unsubscribe();
},
complete: () => {
console.log('done with this');
fail();
}
});
});
test("Uses service-provided timeout when no custom keepAliveTimeoutMs is configured", (done) => {
const id = "abcd-efgh-ijkl-mnop";
uuid.mockImplementationOnce(() => id);
expect.assertions(5);
jest.spyOn(Date.prototype, 'toISOString').mockImplementation(jest.fn(() => {
return "2019-11-13T18:47:04.733Z";
}));
AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = jest.fn((url, protocol) => {
expect(url).toBe('wss://apikeytest.testcustomdomain.com/graphql/realtime?header=eyJob3N0IjoiYXBpa2V5dGVzdC50ZXN0Y3VzdG9tZG9tYWluLmNvbSIsIngtYW16LWRhdGUiOiIyMDE5MTExM1QxODQ3MDRaIiwieC1hcGkta2V5IjoieHh4eHgifQ==&payload=e30=');
expect(protocol).toBe('graphql-ws');
const socket = new myWebSocket();
setTimeout(() => {
socket.close = () => {};
socket.onopen.call(socket, (undefined as unknown as Event));
socket.send = (msg: string) => {
const { type } = JSON.parse(msg);
switch (type) {
case MESSAGE_TYPES.GQL_CONNECTION_INIT:
socket.onmessage.call(socket, {
data: JSON.stringify({
type: MESSAGE_TYPES.GQL_CONNECTION_ACK,
payload: {
connectionTimeoutMs: 99999,
},
})
} as MessageEvent);
setTimeout(() => {
socket.onmessage.call(socket, {
data: JSON.stringify({
id,
type: MESSAGE_TYPES.GQL_DATA,
payload: {
data: { something: 123 },
},
})
} as MessageEvent);
}, 100);
break;
}
};
}, 100);
return socket;
});
const link = new AppSyncRealTimeSubscriptionHandshakeLink({
auth: {
type: AUTH_TYPE.API_KEY,
apiKey: 'xxxxx'
},
region: 'us-west-2',
url: 'https://apikeytest.testcustomdomain.com/graphql',
});
expect(link).toBeInstanceOf(AppSyncRealTimeSubscriptionHandshakeLink);
expect((link as any).keepAliveTimeout).toBeUndefined();
const sub = execute(link, { query }).subscribe({
error: (err) => {
console.log(JSON.stringify(err));
fail();
},
next: (data) => {
expect((link as any).keepAliveTimeout).toBe(99999);
done();
sub.unsubscribe();
},
complete: () => {
console.log('done with this');
fail();
}
});
});
});

@@ -6,2 +6,13 @@ # Change Log

<a name="3.1.0"></a>
# [3.1.0](https://github.com/awslabs/aws-mobile-appsync-sdk-js/compare/aws-appsync-subscription-link@3.0.11...aws-appsync-subscription-link@3.1.0) (2022-06-24)
### Features
* Add keepAliveTimeoutMs config for AppSync WebSocket link ([#724](https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues/724)) ([74b8351](https://github.com/awslabs/aws-mobile-appsync-sdk-js/commit/74b8351))
<a name="3.0.11"></a>

@@ -8,0 +19,0 @@ ## [3.0.11](https://github.com/awslabs/aws-mobile-appsync-sdk-js/compare/aws-appsync-subscription-link@3.0.10...aws-appsync-subscription-link@3.0.11) (2022-05-02)

4

lib/index.d.ts
import { CONTROL_EVENTS_KEY } from "./subscription-handshake-link";
import { ApolloLink } from "@apollo/client/core";
import { UrlInfo } from "./types";
declare function createSubscriptionHandshakeLink(args: UrlInfo, resultsFetcherLink?: ApolloLink): ApolloLink;
import { AppSyncRealTimeSubscriptionConfig } from "./types";
declare function createSubscriptionHandshakeLink(args: AppSyncRealTimeSubscriptionConfig, resultsFetcherLink?: ApolloLink): ApolloLink;
declare function createSubscriptionHandshakeLink(url: string, resultsFetcherLink?: ApolloLink): ApolloLink;
export { CONTROL_EVENTS_KEY, createSubscriptionHandshakeLink };

@@ -6,3 +6,3 @@ /*!

import { ApolloLink, Observable, Operation, FetchResult } from "@apollo/client/core";
import { UrlInfo } from "./types";
import { AppSyncRealTimeSubscriptionConfig } from "./types";
export declare const CONTROL_EVENTS_KEY = "@@controlEvents";

@@ -16,6 +16,6 @@ export declare class AppSyncRealTimeSubscriptionHandshakeLink extends ApolloLink {

private keepAliveTimeoutId;
private keepAliveTimeout;
private keepAliveTimeout?;
private subscriptionObserverMap;
private promiseArray;
constructor({ url: theUrl, region: theRegion, auth: theAuth }: UrlInfo);
constructor({ url: theUrl, region: theRegion, auth: theAuth, keepAliveTimeoutMs }: AppSyncRealTimeSubscriptionConfig);
private isCustomDomain;

@@ -22,0 +22,0 @@ request(operation: Operation): Observable<FetchResult<Record<string, any>, Record<string, any>, Record<string, any>>>;

@@ -93,2 +93,6 @@ "use strict";

/**
* Frequency in milliseconds in which the server sends GQL_CONNECTION_KEEP_ALIVE messages
*/
var SERVER_KEEP_ALIVE_TIMEOUT = 1 * 60 * 1000;
/**
* Default Time in milliseconds to wait for GQL_CONNECTION_KEEP_ALIVE message

@@ -102,6 +106,6 @@ */

function AppSyncRealTimeSubscriptionHandshakeLink(_a) {
var theUrl = _a.url, theRegion = _a.region, theAuth = _a.auth;
var theUrl = _a.url, theRegion = _a.region, theAuth = _a.auth, keepAliveTimeoutMs = _a.keepAliveTimeoutMs;
var _this = _super.call(this) || this;
_this.socketStatus = types_1.SOCKET_STATUS.CLOSED;
_this.keepAliveTimeout = DEFAULT_KEEP_ALIVE_TIMEOUT;
_this.keepAliveTimeout = undefined;
_this.subscriptionObserverMap = new Map();

@@ -112,2 +116,7 @@ _this.promiseArray = [];

_this.auth = theAuth;
_this.keepAliveTimeout = keepAliveTimeoutMs;
if (_this.keepAliveTimeout < SERVER_KEEP_ALIVE_TIMEOUT) {
var configName = 'keepAliveTimeoutMs';
throw new Error(configName + " must be greater than or equal to " + SERVER_KEEP_ALIVE_TIMEOUT + " (" + _this.keepAliveTimeout + " used).");
}
return _this;

@@ -612,8 +621,9 @@ }

_this.awsRealTimeSocket.onmessage = function (message) {
var _a;
logger("subscription message from AWS AppSyncRealTime: " + message.data + " ");
var data = JSON.parse(message.data);
var type = data.type, _a = data.payload, _b = (_a === void 0 ? {} : _a).connectionTimeoutMs, connectionTimeoutMs = _b === void 0 ? DEFAULT_KEEP_ALIVE_TIMEOUT : _b;
var type = data.type, _b = data.payload, _c = (_b === void 0 ? {} : _b).connectionTimeoutMs, connectionTimeoutMs = _c === void 0 ? DEFAULT_KEEP_ALIVE_TIMEOUT : _c;
if (type === types_1.MESSAGE_TYPES.GQL_CONNECTION_ACK) {
ackOk = true;
_this.keepAliveTimeout = connectionTimeoutMs;
_this.keepAliveTimeout = (_a = _this.keepAliveTimeout) !== null && _a !== void 0 ? _a : connectionTimeoutMs;
_this.awsRealTimeSocket.onmessage = _this._handleIncomingSubscriptionMessage.bind(_this);

@@ -632,3 +642,3 @@ _this.awsRealTimeSocket.onerror = function (err) {

if (type === types_1.MESSAGE_TYPES.GQL_CONNECTION_ERROR) {
var _c = data.payload, _d = (_c === void 0 ? {} : _c).errors, _e = (_d === void 0 ? [] : _d)[0], _f = _e === void 0 ? {} : _e, _g = _f.errorType, errorType = _g === void 0 ? "" : _g, _h = _f.errorCode, errorCode = _h === void 0 ? 0 : _h;
var _d = data.payload, _e = (_d === void 0 ? {} : _d).errors, _f = (_e === void 0 ? [] : _e)[0], _g = _f === void 0 ? {} : _f, _h = _g.errorType, errorType = _h === void 0 ? "" : _h, _j = _g.errorCode, errorCode = _j === void 0 ? 0 : _j;
rej({ errorType: errorType, errorCode: errorCode });

@@ -635,0 +645,0 @@ }

@@ -74,2 +74,5 @@ import { AuthOptions } from "aws-appsync-auth-link";

};
export declare type AppSyncRealTimeSubscriptionConfig = UrlInfo & {
keepAliveTimeoutMs?: number;
};
export declare type ObserverQuery = {

@@ -76,0 +79,0 @@ observer: ZenObservable.SubscriptionObserver<any>;

{
"name": "aws-appsync-subscription-link",
"version": "3.0.11",
"version": "3.1.0",
"main": "lib/index.js",

@@ -5,0 +5,0 @@ "license": "Apache-2.0",

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