mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2026-10-05 07:17:04 +00:00
Merge pull request #30944 from DanielRose/socketcluster
Adds type definitions for packages: sc-auth, socketcluster, socketclu…
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
import { ExpiryManager } from "expirymanager";
|
||||
|
||||
const expiryManager = new ExpiryManager();
|
||||
|
||||
const keys = ['1', '2'];
|
||||
|
||||
expiryManager.expire(keys, 1);
|
||||
|
||||
expiryManager.unexpire(keys);
|
||||
|
||||
const expiry: number = expiryManager.getExpiry(keys[0]);
|
||||
|
||||
let expiredKeys = expiryManager.getExpiredKeys();
|
||||
expiredKeys = expiryManager.getExpiredKeys(expiryManager.now());
|
||||
|
||||
expiredKeys = expiryManager.extractExpiredKeys();
|
||||
expiredKeys = expiryManager.extractExpiredKeys(expiryManager.now());
|
||||
|
||||
expiryManager.clear();
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
// Type definitions for expirymanager 0.9
|
||||
// Project: https://github.com/SocketCluster/expirymanager
|
||||
// Definitions by: Daniel Rose <https://github.com/DanielRose>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
export type Key = any;
|
||||
export type Keys = Key[];
|
||||
|
||||
export class ExpiryManager {
|
||||
constructor();
|
||||
|
||||
now(): number;
|
||||
|
||||
expire(keys: Keys, seconds: number): void;
|
||||
unexpire(keys: Keys): void;
|
||||
|
||||
getExpiry(key: Key): number;
|
||||
|
||||
getKeysByExpiry(expiry: number): Keys;
|
||||
|
||||
getExpiredKeys(time?: number): Keys;
|
||||
extractExpiredKeys(time?: number): Keys;
|
||||
|
||||
clear(): void;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"expirymanager-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { FlexiMap } from "fleximap";
|
||||
|
||||
let flexiMap = new FlexiMap();
|
||||
flexiMap = new FlexiMap({ arr: [] });
|
||||
flexiMap = new FlexiMap([{ arr: [] }, { obj: {} }]);
|
||||
|
||||
flexiMap.set('keyA', {arr: [], obj: {}});
|
||||
let result = flexiMap.get(['keyA', 'arr']);
|
||||
|
||||
flexiMap.add(['keyB1', 'keyB2', 'keyB3'], 123);
|
||||
result = flexiMap.get(['keyB1', 'keyB2']);
|
||||
|
||||
const arr = [];
|
||||
arr[5] = 'Hello world';
|
||||
|
||||
flexiMap.set(['keyC1', 'keyC2'], arr);
|
||||
result = flexiMap.get(['keyC1', 'keyC2']);
|
||||
|
||||
flexiMap.set(['itemsA', 0], 'hello');
|
||||
flexiMap.set(['itemsA', 2], 'world');
|
||||
flexiMap.remove(['itemsA', 0]);
|
||||
|
||||
flexiMap.set(['itemsB', 0], 'a');
|
||||
flexiMap.set(['itemsB', 1], 'b');
|
||||
flexiMap.set(['itemsB', 2], 'c');
|
||||
let splicedItems = flexiMap.splice(['itemsB'], 1, 1);
|
||||
splicedItems = flexiMap.splice(['itemsB'], 1, 0, 'b2');
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
// Type definitions for fleximap 0.9
|
||||
// Project: https://github.com/SocketCluster/fleximap
|
||||
// Definitions by: Daniel Rose <https://github.com/DanielRose>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
export type KeyChain = any;
|
||||
|
||||
export class FlexiMap {
|
||||
constructor(object?: any[] | object);
|
||||
|
||||
get(keyChain: KeyChain): any;
|
||||
getRange(keyChain: KeyChain, fromIndex: number, toIndex: number): any;
|
||||
getRaw(keyChain: KeyChain): any;
|
||||
getAll(): any[] | object;
|
||||
|
||||
count(keyChain: KeyChain): number;
|
||||
|
||||
hasImmediateKey(key: string): boolean;
|
||||
hasKey(keyChain: KeyChain): boolean;
|
||||
hasType(keyChain: KeyChain, type: any): boolean;
|
||||
hasValue(keyChain: KeyChain, value: any): boolean;
|
||||
hasObject(keyChain: KeyChain, object: object): boolean;
|
||||
|
||||
set(keyChain: KeyChain, value: any): any;
|
||||
|
||||
add(keyChain: KeyChain, value: any): number;
|
||||
|
||||
concat(keyChain: KeyChain, value: any): any;
|
||||
|
||||
remove(keyChain: KeyChain): any;
|
||||
removeRange(keyChain: KeyChain, fromIndex: number, toIndex: number): any[];
|
||||
removeAll(): void;
|
||||
|
||||
splice(keyChain: KeyChain, index: number, count: number, ...items: any[]): any[];
|
||||
|
||||
pop(keyChain: KeyChain): any[];
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"fleximap-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json"
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// Type definitions for sc-auth 5.0
|
||||
// Project: https://github.com/SocketCluster/sc-auth
|
||||
// Definitions by: Daniel Rose <https://github.com/DanielRose>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.2
|
||||
|
||||
import { VerifyOptions, VerifyCallback, Secret, SignCallback, SignOptions } from "jsonwebtoken";
|
||||
|
||||
export interface SCAuthEngine {
|
||||
verifyToken(signedToken: string, key: string | Buffer, options?: VerifyOptions, callback?: VerifyCallback): void;
|
||||
signToken(token: string | object | Buffer, key: Secret, options?: SignOptions, callback?: SignCallback): void;
|
||||
}
|
||||
|
||||
export class AuthEngine implements SCAuthEngine {
|
||||
constructor();
|
||||
|
||||
verifyToken(signedToken: string, key: string | Buffer, options?: VerifyOptions, callback?: VerifyCallback): void;
|
||||
signToken(token: string | object | Buffer, key: Secret, options?: SignOptions, callback?: SignCallback): void;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* This mostly delegates to jwt, so using its tests as base
|
||||
*/
|
||||
|
||||
import scAuth = require("sc-auth");
|
||||
import fs = require("fs");
|
||||
|
||||
let signedToken = "";
|
||||
let cert: Buffer;
|
||||
|
||||
interface TestObject {
|
||||
foo: string;
|
||||
}
|
||||
|
||||
const testObject = { foo: "bar" };
|
||||
|
||||
const authEngine = new scAuth.AuthEngine();
|
||||
|
||||
// sign with default (HMAC SHA256)
|
||||
authEngine.signToken(testObject, "shhhhh");
|
||||
|
||||
// sign with default (HMAC SHA256) and single audience
|
||||
authEngine.signToken(testObject, "shhhhh", { audience: "theAudience" });
|
||||
|
||||
// sign with default (HMAC SHA256) and multiple audiences
|
||||
authEngine.signToken(testObject, "shhhhh", {
|
||||
audience: ["audience1", "audience2"]
|
||||
});
|
||||
|
||||
// sign with default (HMAC SHA256) and a keyid
|
||||
authEngine.signToken(testObject, "shhhhh", { keyid: "theKeyId" });
|
||||
|
||||
// sign with RSA SHA256
|
||||
cert = fs.readFileSync("private.key"); // get private key
|
||||
authEngine.signToken(testObject, cert, { algorithm: "RS256" });
|
||||
|
||||
// sign with encrypted RSA SHA256 private key (only PEM encoding is supported)
|
||||
const privKey: Buffer = fs.readFileSync("encrypted_private.key"); // get private key
|
||||
const secret = { key: privKey.toString(), passphrase: "keypwd" };
|
||||
authEngine.signToken(testObject, secret, { algorithm: "RS256" }); // the algorithm option is mandatory in this case
|
||||
|
||||
// sign asynchronously
|
||||
authEngine.signToken(testObject, cert, { algorithm: "RS256" }, (err, token) => {
|
||||
signedToken = token;
|
||||
});
|
||||
|
||||
// verify a token symmetric
|
||||
authEngine.verifyToken(signedToken, "shhhhh", {}, (err, decoded) => {
|
||||
const result = decoded as TestObject;
|
||||
|
||||
console.log(result.foo); // bar
|
||||
});
|
||||
|
||||
// use external time for verifying
|
||||
authEngine.verifyToken(signedToken, "shhhhh", { clockTimestamp: 1 }, (err, decoded) => {
|
||||
const result = decoded as TestObject;
|
||||
|
||||
console.log(result.foo); // bar
|
||||
});
|
||||
|
||||
// invalid token
|
||||
authEngine.verifyToken(signedToken, "wrong-secret", {}, (err, decoded) => {
|
||||
console.log(err);
|
||||
|
||||
// decoded undefined
|
||||
});
|
||||
|
||||
// verify a token asymmetric
|
||||
cert = fs.readFileSync("public.pem"); // get public key
|
||||
authEngine.verifyToken(signedToken, cert, {}, (err, decoded) => {
|
||||
const result = decoded as TestObject;
|
||||
|
||||
console.log(result.foo); // bar
|
||||
});
|
||||
|
||||
// verify audience
|
||||
cert = fs.readFileSync("public.pem"); // get public key
|
||||
authEngine.verifyToken(signedToken, cert, { audience: "urn:foo" }, (err, decoded) => {
|
||||
// if audience mismatch, err == invalid audience
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
// verify issuer
|
||||
cert = fs.readFileSync("public.pem"); // get public key
|
||||
authEngine.verifyToken(signedToken, cert, { audience: "urn:foo", issuer: "urn:issuer" }, (err, decoded) => {
|
||||
// if issuer mismatch, err == invalid issuer
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
// verify algorithm
|
||||
cert = fs.readFileSync("public.pem"); // get public key
|
||||
authEngine.verifyToken(signedToken, cert, { algorithms: ["RS256"] }, (err, decoded) => {
|
||||
// if algorithm mismatch, err == invalid algorithm
|
||||
console.log(err);
|
||||
});
|
||||
|
||||
// verify without expiration check
|
||||
cert = fs.readFileSync("public.pem"); // get public key
|
||||
authEngine.verifyToken(signedToken, cert, { ignoreExpiration: true }, (err, decoded) => {
|
||||
// if ignoreExpration == false and token is expired, err == expired token
|
||||
console.log(err);
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"sc-auth-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{ "extends": "dtslint/dt.json" }
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import { EventEmitter } from "events";
|
||||
import { SCBrokerClient } from "sc-broker";
|
||||
import { mapperFunction } from ".";
|
||||
|
||||
export class ClientCluster extends EventEmitter {
|
||||
constructor(clients: SCBrokerClient[]);
|
||||
|
||||
setMapper(mapper: mapperFunction): void;
|
||||
getMapper(): mapperFunction;
|
||||
}
|
||||
Vendored
+160
@@ -0,0 +1,160 @@
|
||||
// Type definitions for sc-broker-cluster 6.1
|
||||
// Project: https://github.com/SocketCluster/sc-broker-cluster
|
||||
// Definitions by: Daniel Rose <https://github.com/DanielRose>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
import { SCServerSocket, SCServer } from "socketcluster-server";
|
||||
import { BrokerStartInfo, BrokerExitInfo } from "socketcluster";
|
||||
import { SpliceOptions, QueryOptions } from "sc-broker";
|
||||
import { SCChannel } from "sc-channel";
|
||||
import { EventEmitter } from "events";
|
||||
import { AsyncResultArrayCallback } from "async";
|
||||
import { KeyChain, FlexiMap } from "fleximap";
|
||||
import { Keys } from "expirymanager";
|
||||
import { ClientCluster } from "./clientcluster";
|
||||
|
||||
export class AbstractDataClient extends EventEmitter {
|
||||
constructor(dataClient: ClientCluster);
|
||||
|
||||
set(keyChain: KeyChain, value: any, getValue?: boolean, callback?: (err?: Error) => void): void;
|
||||
set(keyChain: KeyChain, value: any, callback?: (err?: Error) => void): void;
|
||||
|
||||
expire(keys: Keys, seconds: number, callback?: (err?: Error) => void): void;
|
||||
unexpire(keys: Keys, callback?: (err?: Error) => void): void;
|
||||
|
||||
add(keyChain: KeyChain, value: any, getValue?: boolean, callback?: (err?: Error) => void): void;
|
||||
add(keyChain: KeyChain, value: any, callback?: (err?: Error) => void): void;
|
||||
|
||||
get(keyChain: KeyChain, callback: (err: Error | null, value: any) => void): void;
|
||||
|
||||
getRange(keyChain: KeyChain, fromIndex: number, toIndex: number, callback: (err: Error | null, value: any) => void): void;
|
||||
getRange(keyChain: KeyChain, fromIndex: number, callback: (err: Error | null, value: any) => void): void;
|
||||
|
||||
getAll(callback: (err: Error | null, value: any[] | object) => void): void;
|
||||
|
||||
count(keyChain: KeyChain, callback: (err: Error | null, value: number) => void): void;
|
||||
|
||||
remove(keyChain: KeyChain, getValue?: boolean, callback?: (err?: Error) => void): void;
|
||||
remove(keyChain: KeyChain, callback?: (err?: Error) => void): void;
|
||||
|
||||
removeRange(keyChain: KeyChain, fromIndex: number, toIndex?: number, getValue?: boolean, callback?: (err?: Error) => void): void;
|
||||
removeRange(keyChain: KeyChain, fromIndex: number, toIndex?: number, callback?: (err?: Error) => void): void;
|
||||
removeRange(keyChain: KeyChain, fromIndex: number, callback?: (err?: Error) => void): void;
|
||||
|
||||
removeAll(callback?: (err: Error) => void): void;
|
||||
|
||||
splice(keyChain: KeyChain, options?: SpliceOptions, callback?: (err?: Error) => void): void;
|
||||
splice(keyChain: KeyChain, callback?: (err?: Error) => void): void;
|
||||
|
||||
pop(keyChain: KeyChain, callback: (err: Error | null, data: any) => void): void;
|
||||
|
||||
hasKey(keyChain: KeyChain, callback: (err: Error | null, data: boolean) => void): void;
|
||||
|
||||
extractKeys(keyChain: KeyChain): string[];
|
||||
|
||||
extractValues(keyChain: KeyChain): any[];
|
||||
|
||||
exec(query: (datamap: FlexiMap) => void, options?: QueryOptions, callback?: (err: Error | null, data: any) => void): void;
|
||||
exec(query: (datamap: FlexiMap) => void, callback: (err: Error | null, data: any) => void): void;
|
||||
}
|
||||
|
||||
export type handlerFunction = (data: any) => void;
|
||||
|
||||
export type mapperFunction = (keyChain: KeyChain, method: string, clientIds: number[]) => number | number[];
|
||||
|
||||
/**
|
||||
* The exchange object is a top-level SCBrokerClient which lets you publish events and manipulate data within your brokers - It represents a cluster of 1 or more brokers.
|
||||
*/
|
||||
export class SCExchange extends AbstractDataClient {
|
||||
constructor(privateClientCluster: ClientCluster, publicClientCluster: ClientCluster, ioClusterClient: Client);
|
||||
|
||||
send(data: any, mapIndex: number | string | string[] | null, callback?: (err?: Error) => void): void;
|
||||
|
||||
publish(channelName: string, data: any, callback: (err?: Error) => void): void;
|
||||
|
||||
subscribe(channelName: string): SCChannel;
|
||||
unsubscribe(channelName: string): void;
|
||||
|
||||
channel(channelName: string): SCChannel;
|
||||
destroyChannel(channelName: string): void;
|
||||
|
||||
subscriptions(includePending?: boolean): string[];
|
||||
isSubscribed(channelName: string, includePending?: boolean): boolean;
|
||||
|
||||
watch(channelName: string, handler: handlerFunction): void;
|
||||
unwatch(channelName: string, handler?: handlerFunction): void;
|
||||
watchers(channelName: string): handlerFunction[];
|
||||
|
||||
setMapper(mapper: mapperFunction): void;
|
||||
getMapper(): mapperFunction;
|
||||
|
||||
map(keyChain: KeyChain, method: string): { type: string; targets: Client[] };
|
||||
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export interface SCBrokerClusterServerOptions {
|
||||
brokers: string[];
|
||||
debug?: boolean;
|
||||
inspect?: boolean;
|
||||
instanceId?: string;
|
||||
secretKey?: string;
|
||||
expiryAccuracy?: number;
|
||||
downgradeToUser: number | string;
|
||||
appBrokerControllerPath?: string;
|
||||
processTermTimeout?: number;
|
||||
ipcAckTimeout?: number;
|
||||
brokerOptions?: SCServer.SCServerOptions;
|
||||
}
|
||||
|
||||
export class Server extends EventEmitter {
|
||||
constructor(options: SCBrokerClusterServerOptions);
|
||||
|
||||
on(event: "brokerStart", listener: (brokerInfo: BrokerStartInfo) => void): this;
|
||||
on(event: "brokerExit", listener: (brokerInfo: BrokerExitInfo) => void): this;
|
||||
on(event: "brokerMessage", listener: (brokerId: string, data: any, callback: (err: Error | null, data: any) => void) => void): this;
|
||||
on(event: "ready", listener: () => void): this;
|
||||
on(event: "error", listener: (err?: Error) => void): this;
|
||||
|
||||
sendToBroker(brokerId: string, data: any, callback: (err: Error | null, data: any) => void): void;
|
||||
killBrokers(): void;
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export interface SCBrokerClusterClientOptions {
|
||||
brokers: string[];
|
||||
secretKey?: string;
|
||||
pubSubBatchDuration?: number;
|
||||
connectRetryErrorThreshold: number;
|
||||
}
|
||||
|
||||
export interface MessagePacket {
|
||||
channel: string;
|
||||
data: any;
|
||||
}
|
||||
|
||||
export class Client extends EventEmitter {
|
||||
constructor(options: SCBrokerClusterClientOptions);
|
||||
|
||||
exchange(): SCExchange;
|
||||
|
||||
options: SCBrokerClusterClientOptions;
|
||||
|
||||
on(event: "error", listener: (err?: Error) => void): this;
|
||||
on(event: "warning", listener: (warning?: Error) => void): this;
|
||||
on(event: "ready", listener: () => void): this;
|
||||
on(event: "message", listener: (packet: MessagePacket) => void): this;
|
||||
|
||||
destroy(callback: AsyncResultArrayCallback<SCExchange>): void;
|
||||
|
||||
subscribe(channel: string, callback: (err?: Error) => void): void;
|
||||
unsubscribe(channel: string, callback: () => void): void;
|
||||
unsubscribeAll(callback: () => void): void;
|
||||
isSubscribed(channel: string, includePending: boolean): boolean;
|
||||
|
||||
subscribeSocket(socket: SCServerSocket, channel: string, callback?: (err?: Error) => void): void;
|
||||
unsubscribeSocket(socket: SCServerSocket, channel: string, callback?: () => void): void;
|
||||
|
||||
setSCServer(scServer: SCServer): void;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Client } from "sc-broker-cluster";
|
||||
import { SCServer, SCServerSocket } from "socketcluster-server";
|
||||
import WebSocket = require("ws");
|
||||
|
||||
const client = new Client({
|
||||
brokers: [],
|
||||
secretKey: "secretKey",
|
||||
pubSubBatchDuration: 100,
|
||||
connectRetryErrorThreshold: 5
|
||||
});
|
||||
|
||||
client.on("error", err => {});
|
||||
client.on("warning", err => {});
|
||||
|
||||
const exchange = client.exchange();
|
||||
|
||||
const scServer = new SCServer();
|
||||
client.setSCServer(scServer);
|
||||
|
||||
client.once("ready", () => {});
|
||||
|
||||
const wsSocket = new WebSocket("address");
|
||||
const socket = new SCServerSocket("id", scServer, wsSocket);
|
||||
client.subscribeSocket(socket, "channelName", err => {});
|
||||
|
||||
client.unsubscribeSocket(socket, "channelName");
|
||||
|
||||
const data: any = {};
|
||||
exchange.publish("channelName", data, err => {});
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import SCBroker = require("sc-broker/scbroker");
|
||||
|
||||
export = SCBroker;
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"clientcluster.d.ts",
|
||||
"scbroker.d.ts",
|
||||
"sc-broker-cluster-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json"
|
||||
}
|
||||
Vendored
+165
@@ -0,0 +1,165 @@
|
||||
// Type definitions for sc-broker 5.1
|
||||
// Project: https://github.com/SocketCluster/sc-broker
|
||||
// Definitions by: Daniel Rose <https://github.com/DanielRose>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
import { SCServer } from "socketcluster-server";
|
||||
import { WorkerExitInfo } from "socketcluster";
|
||||
import { EventEmitter } from "events";
|
||||
import { KeyChain, FlexiMap } from "fleximap";
|
||||
import { Keys, Key } from "expirymanager";
|
||||
|
||||
export interface SCBrokerServerOptions {
|
||||
id?: string;
|
||||
instanceId?: string;
|
||||
debug?: boolean;
|
||||
inspect?: boolean;
|
||||
socketPath?: string;
|
||||
port?: number;
|
||||
expiryAccuracy?: number;
|
||||
downgradeToUser: number | string;
|
||||
brokerControllerPath?: string;
|
||||
processTermTimeout?: number;
|
||||
ipcAckTimeout?: number;
|
||||
secretKey?: string;
|
||||
brokerOptions?: SCServer.SCServerOptions;
|
||||
}
|
||||
|
||||
export interface SCBrokerServer extends EventEmitter {
|
||||
options: SCBrokerServerOptions;
|
||||
socketPath?: string;
|
||||
port?: number;
|
||||
ipcAckTimeout: number;
|
||||
|
||||
on(event: "error", listener: (err?: Error) => void): this;
|
||||
on(event: "brokerMessage", listener: (brokerId: string, data: any, callback: (err: Error | null, data: any) => void) => void): this;
|
||||
on(event: "ready", listener: (data: any) => void): this;
|
||||
on(event: "exit", listener: (data: WorkerExitInfo) => void): this;
|
||||
|
||||
sendToBroker(data: any, callback?: (err: Error | null, data: any, brokerId: string) => void): void;
|
||||
}
|
||||
|
||||
export function createServer(options?: SCBrokerServerOptions): SCBrokerServer;
|
||||
|
||||
export interface AutoReconnectOptions {
|
||||
initialDelay?: number;
|
||||
randomness?: number;
|
||||
multiplier?: number;
|
||||
maxDelay?: number;
|
||||
}
|
||||
|
||||
export interface SCBrokerClientOptions {
|
||||
secretKey?: string;
|
||||
timeout?: number;
|
||||
socketPath?: string;
|
||||
port?: number;
|
||||
host?: string;
|
||||
autoReconnect?: boolean;
|
||||
autoReconnectOptions?: AutoReconnectOptions;
|
||||
connectRetryErrorThreshold?: number;
|
||||
pubSubBatchDuration?: number;
|
||||
}
|
||||
|
||||
export interface QueryOptions {
|
||||
baseKey?: KeyChain;
|
||||
noAck?: boolean;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
export interface SpliceOptions {
|
||||
index?: number;
|
||||
count?: number;
|
||||
items?: any[];
|
||||
getValue?: boolean;
|
||||
noAck?: boolean;
|
||||
}
|
||||
|
||||
export interface SCBrokerClient extends EventEmitter {
|
||||
readonly CONNECTED: "connected";
|
||||
readonly CONNECTING: "connecting";
|
||||
readonly DISCONNECTED: "disconnected";
|
||||
|
||||
socketPath?: string;
|
||||
port?: number;
|
||||
host?: string;
|
||||
autoReconnect: boolean;
|
||||
autoReconnectOptions?: AutoReconnectOptions;
|
||||
connectRetryErrorThreshold: number;
|
||||
state: "connected" | "connecting" | "disconnected";
|
||||
connectAttempts: number;
|
||||
pendingReconnect: boolean;
|
||||
pendingReconnectTimeout: number | null;
|
||||
|
||||
on(event: "error", listener: (err?: Error) => void): this;
|
||||
on(event: "warning", listener: (warning?: Error) => void): this;
|
||||
on(event: "ready", listener: (data: any) => void): this;
|
||||
on(event: "message", listener: (channel: string, data: any) => void): this;
|
||||
on(event: "subscribeFail", listener: (err: Error | null, channel: string) => void): this;
|
||||
on(event: "subscribe", listener: (channel: string) => void): this;
|
||||
on(event: "unsubscribe", listener: () => void): this;
|
||||
|
||||
isConnected(): boolean;
|
||||
|
||||
subscribe(channel: string, ackCallback: (err?: Error) => void, force?: boolean): void;
|
||||
unsubscribe(channel: string, ackCallback: (err?: Error) => void): void;
|
||||
|
||||
subscriptions(includePending?: boolean): string[];
|
||||
isSubscribed(channel: string, includePending?: boolean): boolean;
|
||||
|
||||
publish(channel: string, data: any, callback: (err?: Error) => void): void;
|
||||
|
||||
send(data: any, callback: (err?: Error) => void): void;
|
||||
|
||||
set(keyChain: KeyChain, value: any, getValue?: boolean, callback?: (err?: Error) => void): void;
|
||||
set(keyChain: KeyChain, value: any, callback?: (err?: Error) => void): void;
|
||||
|
||||
expire(keys: Keys, seconds: number, callback?: (err?: Error) => void): void;
|
||||
unexpire(keys: Keys, callback?: (err?: Error) => void): void;
|
||||
getExpiry(key: Key, callback?: (err?: Error) => void): number;
|
||||
|
||||
add(keyChain: KeyChain, value: any, getValue?: boolean, callback?: (err?: Error) => void): void;
|
||||
add(keyChain: KeyChain, value: any, callback?: (err?: Error) => void): void;
|
||||
|
||||
concat(keyChain: KeyChain, value: any, getValue?: boolean, callback?: (err?: Error) => void): void;
|
||||
concat(keyChain: KeyChain, value: any, callback?: (err?: Error) => void): void;
|
||||
|
||||
get(keyChain: KeyChain, callback: (err: Error | null, value: any) => void): void;
|
||||
|
||||
getRange(keyChain: KeyChain, fromIndex: number, toIndex: number, callback: (err: Error | null, value: any) => void): void;
|
||||
getRange(keyChain: KeyChain, fromIndex: number, callback: (err: Error | null, value: any) => void): void;
|
||||
|
||||
getAll(callback: (err: Error | null, value: any[] | object) => void): void;
|
||||
|
||||
count(keyChain: KeyChain, callback: (err: Error | null, value: number) => void): void;
|
||||
|
||||
exec(query: (datamap: FlexiMap) => void, options?: QueryOptions, callback?: (err: Error | null, data: any) => void): void;
|
||||
exec(query: (datamap: FlexiMap) => void, callback: (err: Error | null, data: any) => void): void;
|
||||
|
||||
query(query: (datamap: FlexiMap) => void, data?: any, callback?: (err: Error | null, data: any) => void): void;
|
||||
query(query: (datamap: FlexiMap) => void, callback: (err: Error | null, data: any) => void): void;
|
||||
|
||||
remove(keyChain: KeyChain, getValue?: boolean, callback?: (err?: Error) => void): void;
|
||||
remove(keyChain: KeyChain, callback?: (err?: Error) => void): void;
|
||||
|
||||
removeRange(keyChain: KeyChain, fromIndex: number, toIndex?: number, getValue?: boolean, callback?: (err?: Error) => void): void;
|
||||
removeRange(keyChain: KeyChain, fromIndex: number, toIndex?: number, callback?: (err?: Error) => void): void;
|
||||
removeRange(keyChain: KeyChain, fromIndex: number, callback?: (err?: Error) => void): void;
|
||||
|
||||
removeAll(callback?: (err: Error) => void): void;
|
||||
|
||||
splice(keyChain: KeyChain, options?: SpliceOptions, callback?: (err?: Error) => void): void;
|
||||
splice(keyChain: KeyChain, callback?: (err?: Error) => void): void;
|
||||
|
||||
pop(keyChain: KeyChain, callback: (err: Error | null, data: any) => void): void;
|
||||
|
||||
hasKey(keyChain: KeyChain, callback: (err: Error | null, data: boolean) => void): void;
|
||||
|
||||
extractKeys(keyChain: KeyChain): string[];
|
||||
|
||||
extractValues(keyChain: KeyChain): any[];
|
||||
|
||||
end(callback: (err?: Error) => void): void;
|
||||
}
|
||||
|
||||
export function createClient(options?: SCBrokerClientOptions): SCBrokerClient;
|
||||
@@ -0,0 +1,58 @@
|
||||
import { SCServer, SCServerSocket } from "socketcluster-server";
|
||||
import SCBroker = require("sc-broker/scbroker");
|
||||
import { FlexiMap } from "fleximap";
|
||||
import { ExpiryManager } from "expirymanager";
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
/// SCBroker tests
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
const options: SCServer.SCServerOptions = { port: 80 };
|
||||
|
||||
let scBroker = new SCBroker();
|
||||
scBroker = new SCBroker(options);
|
||||
scBroker.options = { environment: "prod" };
|
||||
|
||||
const id: number = scBroker.id;
|
||||
const instanceId: number = scBroker.instanceId;
|
||||
const dataMap: FlexiMap = scBroker.dataMap;
|
||||
const dataExpirer: ExpiryManager = scBroker.dataExpirer;
|
||||
const subscriptions = scBroker.subscriptions;
|
||||
|
||||
const socket: SCServerSocket = subscriptions[1]["test"];
|
||||
|
||||
scBroker.on("subscribe", channel => {
|
||||
const subscribeChannel: string = channel;
|
||||
});
|
||||
scBroker.on("unsubscribe", channel => {
|
||||
const unsubscribeChannel: string = channel;
|
||||
});
|
||||
scBroker.on("publish", (channel, data) => {
|
||||
const publishChannel: string = channel;
|
||||
const publishData: any = data;
|
||||
});
|
||||
scBroker.on("masterMessage", (data, masterMessageResponse) => {
|
||||
const masterMessageData: any = data;
|
||||
masterMessageResponse(null, "test");
|
||||
masterMessageResponse(new Error(), null);
|
||||
});
|
||||
|
||||
scBroker.publish("testChannel", 123);
|
||||
|
||||
scBroker.exec(dataMap => {
|
||||
dataMap.set(["main", "message"], "Message");
|
||||
return dataMap.get(["main"]);
|
||||
});
|
||||
|
||||
scBroker.sendToMaster("data");
|
||||
scBroker.sendToMaster(123, (err, response) => {
|
||||
if (!err) {
|
||||
const answer = response;
|
||||
}
|
||||
});
|
||||
|
||||
class MyBroker extends SCBroker {
|
||||
run() {
|
||||
this.on("subscribe", channel => {});
|
||||
}
|
||||
}
|
||||
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
import { EventEmitter } from "events";
|
||||
import { SCServer, SCServerSocket } from "socketcluster-server";
|
||||
import { FlexiMap, KeyChain } from "fleximap";
|
||||
import { ExpiryManager } from "expirymanager";
|
||||
|
||||
export = SCBroker;
|
||||
|
||||
interface Subscriptions {
|
||||
[socketId: number]: {
|
||||
[channel: string]: SCServerSocket;
|
||||
};
|
||||
}
|
||||
|
||||
declare class SCBroker extends EventEmitter {
|
||||
id: number;
|
||||
options: SCServer.SCServerOptions;
|
||||
instanceId: number;
|
||||
dataMap: FlexiMap;
|
||||
dataExpirer: ExpiryManager;
|
||||
subscriptions: Subscriptions;
|
||||
|
||||
constructor(options?: SCServer.SCServerOptions);
|
||||
|
||||
on(event: "subscribe" | "unsubscribe", listener: (channel: string) => void): this;
|
||||
on(event: "publish", listener: (channel: string, data: any) => void): this;
|
||||
on(event: "masterMessage", listener: (data: any, respond: (err: Error | null, responseData: any) => void) => void): this;
|
||||
|
||||
publish(channel: string, message: any): void;
|
||||
run(): void;
|
||||
exec(query: (dataMap: FlexiMap, dataExpirer: ExpiryManager, subscriptions: Subscriptions) => any, baseKey?: KeyChain): any;
|
||||
sendToMaster(data: any, callback?: (err: Error | null, responseData: any) => void): void;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"scbroker.d.ts",
|
||||
"sc-broker-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json"
|
||||
}
|
||||
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
// Type definitions for sc-channel 1.2
|
||||
// Project: https://github.com/SocketCluster/sc-channel
|
||||
// Definitions by: Daniel Rose <https://github.com/DanielRose>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
import Emitter = require("component-emitter");
|
||||
import { SCExchange, handlerFunction } from "sc-broker-cluster";
|
||||
|
||||
export interface SCChannelOptions {
|
||||
waitForAuth?: boolean;
|
||||
batch?: boolean;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
export class SCChannel extends Emitter {
|
||||
readonly PENDING: "pending";
|
||||
readonly SUBSCRIBED: "subscribed";
|
||||
readonly UNSUBSCRIBED: "unsubscribed";
|
||||
|
||||
name: string;
|
||||
state: ChannelState;
|
||||
waitForAuth: boolean;
|
||||
batch: boolean;
|
||||
data: any;
|
||||
|
||||
constructor(name: string, client: SCExchange, options?: SCChannelOptions);
|
||||
|
||||
setOptions(options?: SCChannelOptions): void;
|
||||
getState(): "pending" | "subscribed" | "unsubscribed";
|
||||
|
||||
subscribe(options?: any): void;
|
||||
unsubscribe(): void;
|
||||
isSubscribed(includePending?: boolean): boolean;
|
||||
|
||||
publish(data: any, callback?: (err?: Error) => void): void;
|
||||
|
||||
watch(handler: handlerFunction): void;
|
||||
unwatch(handler?: handlerFunction): void;
|
||||
watchers(): handlerFunction[];
|
||||
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export type ChannelState = "pending" | "subscribed" | "unsubscribed";
|
||||
@@ -0,0 +1,33 @@
|
||||
import { SCChannel, SCChannelOptions } from "sc-channel";
|
||||
import { handlerFunction, Client, SCBrokerClusterClientOptions } from "sc-broker-cluster";
|
||||
|
||||
const clientOptions: SCBrokerClusterClientOptions = { brokers: [], connectRetryErrorThreshold: 0 };
|
||||
const client = new Client(clientOptions);
|
||||
|
||||
let channel = new SCChannel("channelName", client.exchange());
|
||||
const channelOptions: SCChannelOptions = {};
|
||||
channel = new SCChannel("channelName", client.exchange(), channelOptions);
|
||||
|
||||
channel.state = channel.PENDING;
|
||||
channel.state = channel.SUBSCRIBED;
|
||||
channel.state = channel.UNSUBSCRIBED;
|
||||
|
||||
const channelName: string = channel.name;
|
||||
|
||||
const handler: handlerFunction = () => { };
|
||||
|
||||
channel.watch(handler);
|
||||
channel.unwatch();
|
||||
|
||||
channel.subscribe();
|
||||
channel.subscribe(channelOptions);
|
||||
channel.unsubscribe();
|
||||
|
||||
const data: any = channel.data;
|
||||
|
||||
channel.emit("subscribe", channelName);
|
||||
channel.emit("unsubscribe", channelName);
|
||||
|
||||
channel.setOptions(channelOptions);
|
||||
|
||||
channel.publish(data);
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"sc-channel-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// Type definitions for socketcluster-client 13.0
|
||||
// Project: https://github.com/SocketCluster/socketcluster-client
|
||||
// Definitions by: Daniel Rose <https://github.com/DanielRose>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
import { SCAuthEngine } from "sc-auth";
|
||||
import { SCServer } from "socketcluster-server";
|
||||
|
||||
export import SCClientSocket = require("./lib/scclientsocket");
|
||||
|
||||
export function create(options?: SCClientSocket.ClientOptions): SCClientSocket;
|
||||
|
||||
/** @deprecated */
|
||||
export function connect(options?: SCClientSocket.ClientOptions): SCClientSocket;
|
||||
|
||||
export function destroy(socket: SCClientSocket): void;
|
||||
|
||||
export const clients: {
|
||||
[id: string]: SCClientSocket;
|
||||
};
|
||||
|
||||
export const version: string;
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
import Emitter = require("component-emitter");
|
||||
import { SCServer } from "socketcluster-server";
|
||||
import { SCAuthEngine } from "sc-auth";
|
||||
import { SCChannel, SCChannelOptions, ChannelState } from "sc-channel";
|
||||
import WebSocket = require("ws");
|
||||
|
||||
declare class SCClientSocket extends Emitter {
|
||||
constructor(opts: SCClientSocket.ClientOptions);
|
||||
|
||||
id: string;
|
||||
|
||||
channels: {
|
||||
[channelName: string]: SCChannel;
|
||||
};
|
||||
|
||||
CONNECTING: "connecting";
|
||||
OPEN: "open";
|
||||
CLOSED: "closed";
|
||||
|
||||
state: SCClientSocket.States;
|
||||
getState(): SCClientSocket.States;
|
||||
|
||||
AUTHENTICATED: "authenticated";
|
||||
UNAUTHENTICATED: "unauthenticated";
|
||||
|
||||
authState: SCClientSocket.AuthStates;
|
||||
|
||||
PENDING: "pending";
|
||||
|
||||
pendingReconnect: boolean;
|
||||
pendingReconnectTimeout: number;
|
||||
|
||||
getBytesReceived(): number;
|
||||
|
||||
deauthenticate(callback?: (err: Error) => void): void;
|
||||
|
||||
connect(): void;
|
||||
open(): void;
|
||||
disconnect(code?: number, data?: string | object): void;
|
||||
reconnect(code?: number, data?: string | object): void;
|
||||
destroy(code?: number, data?: string | object): void;
|
||||
|
||||
decodeBase64(encodedString: string): string;
|
||||
encodeBase64(decodedString: string): string;
|
||||
|
||||
getAuthToken(): object | null;
|
||||
authToken: object | null;
|
||||
|
||||
getSignedAuthToken(): string | null;
|
||||
signedAuthToken: string | null;
|
||||
|
||||
// Perform client-initiated authentication by providing an encrypted token string.
|
||||
authenticate(signedAuthToken: string, callback?: (err: Error, authStatus: SCClientSocket.AuthStatus) => void): void;
|
||||
|
||||
decode(message: any): any;
|
||||
encode(object: any): any;
|
||||
|
||||
send(data: any): void;
|
||||
|
||||
emit(event: string, data: any, callback?: (err: Error, responseData: any) => void): void;
|
||||
|
||||
publish(channelName: string, data: any, callback?: (err: Error, ackData: any) => void): void;
|
||||
|
||||
subscribe(channelName: string, options?: SCChannelOptions): SCChannel;
|
||||
unsubscribe(channelName: string): void;
|
||||
|
||||
channel(channelName: string, options?: SCChannelOptions): SCChannel;
|
||||
|
||||
destroyChannel(channelName: string): void;
|
||||
|
||||
subscriptions(includePending?: boolean): string[];
|
||||
isSubscribed(channelName: string, includePending?: boolean): boolean;
|
||||
|
||||
processPendingSubscriptions(): void;
|
||||
|
||||
watch(channelName: string, handler: SCClientSocket.WatcherFunction): void;
|
||||
unwatch(channelName: string, handler?: SCClientSocket.WatcherFunction): void;
|
||||
watchers(channelName: string): SCClientSocket.WatcherFunction[];
|
||||
|
||||
on(event: "connecting", listener: () => void): this;
|
||||
on(event: "connect", listener: (status: SCClientSocket.ConnectStatus, processSubscriptions: () => void) => void): this;
|
||||
on(event: "connectAbort" | "disconnect" | "close", listener: (code: number, data: string | object) => void): this;
|
||||
|
||||
on(event: "kickOut", listener: (message: string, channelName: string) => void): this;
|
||||
|
||||
on(event: "authenticate", listener: (signedAuthToken: string | null) => void): this;
|
||||
on(event: "deauthenticate", listener: (oldSignedToken: string | null) => void): this;
|
||||
on(event: "authStateChange", listener: (stateChangeData: SCClientSocket.AuthStateChangeData) => void): this;
|
||||
on(event: "removeAuthToken", listener: (oldToken: object | null) => void): this;
|
||||
|
||||
on(event: "subscribe" | "subscribeRequest", listener: (channelName: string, subscriptionOptions: SCChannelOptions) => void): this;
|
||||
on(event: "subscribeStateChange", listener: (stateChangeData: SCClientSocket.SubscribeStateChangeData) => void): this;
|
||||
on(event: "subscribeFail", listener: (err: Error, channelName: string, subscriptionOptions: SCChannelOptions) => void): this;
|
||||
on(event: "unsubscribe", listener: (channelName: string) => void): this;
|
||||
|
||||
on(event: "error", listener: (err: Error) => void): this;
|
||||
|
||||
on(event: "raw", listener: (data: any) => void): this;
|
||||
on(event: "message", listener: (message: WebSocket.Data) => void): this;
|
||||
|
||||
// Implements Emitter interface
|
||||
|
||||
// tslint:disable:ban-types
|
||||
// tslint:disable:adjacent-overload-signatures
|
||||
on(event: string, listener: Function): this;
|
||||
once(event: string, listener: Function): this;
|
||||
off(event?: string, listener?: Function): this;
|
||||
emit(event: string, ...args: any[]): boolean;
|
||||
listeners(event: string): Function[];
|
||||
hasListeners(event: string): boolean;
|
||||
// tslint:enable:adjacent-overload-signatures
|
||||
// tslint:enable:ban-types
|
||||
}
|
||||
|
||||
export = SCClientSocket;
|
||||
|
||||
declare namespace SCClientSocket {
|
||||
interface ClientOptions {
|
||||
host?: string;
|
||||
|
||||
// Defaults to the current host (read from the URL).
|
||||
hostname?: string;
|
||||
|
||||
// Defaults to false.
|
||||
secure?: boolean;
|
||||
|
||||
// Defaults to 80 if !secure otherwise defaults to 443.
|
||||
port?: number;
|
||||
|
||||
// The URL which SC uses to make the initial handshake for the WebSocket. Defaults to '/socketcluster/'.
|
||||
path?: string;
|
||||
|
||||
// A map of key-value pairs which will be used as query parameters for the initial HTTP handshake which will initiate the WebSocket connection.
|
||||
query?: string | { [key: string]: string };
|
||||
|
||||
// (milliseconds) - This is the timeout for getting a response to a SCSocket emit event (when a callback is provided).
|
||||
ackTimeout?: number;
|
||||
|
||||
// (milliseconds)
|
||||
connectTimeout?: number;
|
||||
|
||||
// Whether or not to automatically connect the socket as soon as it is created. Default is true.
|
||||
autoConnect?: boolean;
|
||||
|
||||
// Whether or not to automatically reconnect the socket when it loses the connection.
|
||||
autoReconnect?: boolean;
|
||||
|
||||
// Valid properties are: initialDelay (milliseconds), randomness (milliseconds), multiplier (decimal; default is 1.5) and maxDelay (milliseconds).
|
||||
autoReconnectOptions?: AutoReconnectOptions;
|
||||
|
||||
// Whether or not a client automatically disconnects on page unload. If enabled, the client will disconnect when a user navigates away from the page.
|
||||
// This can happen when a user closes the tab/window, clicks a link to leave the page, or types a new URL into the address bar. Defaults to true.
|
||||
disconnectOnUnload?: boolean;
|
||||
|
||||
// Turn on/off per-message deflate compression. If this is true, you need to make sure that this property is also set to true on the server-side.
|
||||
// Note that this option is only relevant when running the client from Node.js. Most modern browsers will automatically use perMessageDeflate so
|
||||
// you only need to turn it on from the server-side.
|
||||
perMessageDeflate?: boolean;
|
||||
|
||||
// Defaults to true; multiplexing allows you to reuse a socket instead of creating a second socket to the same address.
|
||||
multiplex?: boolean;
|
||||
|
||||
// Defaults to null (0 milliseconds); this property affects channel subscription batching; it determines the period in milliseconds for batching
|
||||
// multiple subscription requests together. It only affects channels that have the batch option set to true. A value of null or 0 means that all
|
||||
// subscribe or unsubscribe requests which were made within the same call stack will be batched together. This property was introduced on the
|
||||
// client-side in SC version 8 (both the client and server versions need to be >= 8.0.0). Note that there is also a separate property with the
|
||||
// same name which can be configured on the server.
|
||||
pubSubBatchDuration?: number;
|
||||
|
||||
// Whether or not to add a timestamp to the WebSocket handshake request.
|
||||
timestampRequests?: boolean;
|
||||
|
||||
// The query parameter name to use to hold the timestamp.
|
||||
timestampParam?: string;
|
||||
|
||||
// A custom engine to use for storing and loading JWT auth tokens on the client side.
|
||||
authEngine?: SCAuthEngine | null;
|
||||
|
||||
// The name of the JWT auth token (provided to the authEngine - By default this is the localStorage variable name); defaults to 'socketCluster.authToken'.
|
||||
authTokenName?: string;
|
||||
|
||||
// The type to use to represent binary on the client. Defaults to 'arraybuffer'.
|
||||
binaryType?: string;
|
||||
|
||||
// Set this to false during debugging - Otherwise client connection will fail when using self-signed certificates.
|
||||
rejectUnauthorized?: boolean;
|
||||
|
||||
// If you set this to true, any data/objects/arrays that you pass to the client socket will be cloned before being sent/queued up. If the socket
|
||||
// is disconnected and you emit an event, it will be added to a queue which will be processed upon reconnection. The cloneData option is false
|
||||
// by default; this means that if you emit/publish an object and that object changes somewhere else in your code before the queue is processed,
|
||||
// then the changed version of that object will be sent out to the server.
|
||||
cloneData?: boolean;
|
||||
|
||||
// This is true by default. If you set this to false, then the socket will not automatically try to subscribe to pending subscriptions on
|
||||
// connect - Instead, you will have to manually invoke the processSubscriptions callback from inside the 'connect' event handler on the client side.
|
||||
// See SCSocket Client API. This gives you more fine-grained control with regards to when pending subscriptions are processed after the socket
|
||||
// connection is established (or re-established).
|
||||
autoSubscribeOnConnect?: boolean;
|
||||
|
||||
// Lets you set a custom codec engine. This allows you to specify how data gets encoded before being sent over the wire and how it gets decoded
|
||||
// once it reaches the other side. The codecEngine must be an object which exposes an encode(object) and a decode(encodedData) function.
|
||||
// The encode function can return any data type - Commonly a string or a Buffer/ArrayBuffer. The decode function needs to return a JavaScript
|
||||
// object which adheres to the SC protocol. The idea of using a custom codec is that it allows you to compress SC packets in any format you like
|
||||
// (optimized for any use case) - By decoding these packets back into their original protocol form, SC will be able process them appropriately.
|
||||
// Note that if you provide a codecEngine when creating a client socket see 'codecEngine', you will need to make sure that the server uses the
|
||||
// same codec by passing the same engine to `worker.scServer.setCodecEngine(codecEngine)` when your SC worker initializes on the server side
|
||||
// (see 'setCodecEngine' method here). The default codec engine used by SC is here.
|
||||
codecEngine?: SCServer.SCCodecEngine | null;
|
||||
|
||||
// A prefix to add to the channel names.
|
||||
channelPrefix?: string | null;
|
||||
|
||||
subscriptionRetryOptions?: object | null;
|
||||
}
|
||||
|
||||
interface AutoReconnectOptions {
|
||||
initialDelay?: number;
|
||||
randomness?: number;
|
||||
multiplier?: number;
|
||||
maxDelay?: number;
|
||||
}
|
||||
|
||||
interface AuthStatus {
|
||||
isAuthenticated: AuthStates;
|
||||
authError: Error;
|
||||
}
|
||||
|
||||
interface AuthStateChangeData {
|
||||
oldState: AuthStates;
|
||||
newState: AuthStates;
|
||||
}
|
||||
|
||||
interface ConnectStatus {
|
||||
id: string;
|
||||
pingTimeout: number;
|
||||
isAuthenticated: boolean;
|
||||
authToken?: object;
|
||||
authError?: Error;
|
||||
}
|
||||
|
||||
interface SubscribeStateChangeData {
|
||||
channel: string;
|
||||
oldState: ChannelState;
|
||||
newState: ChannelState;
|
||||
subscriptionOptions: SCChannelOptions;
|
||||
}
|
||||
|
||||
type WatcherFunction = (data: any) => void;
|
||||
type AuthStates = "authenticated" | "unauthenticated";
|
||||
type States = "connecting" | "open" | "closed";
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
// Adapted from README
|
||||
|
||||
import { create, destroy } from "socketcluster-client";
|
||||
import { ClientOptions } from "socketcluster-client/lib/scclientsocket";
|
||||
|
||||
const secureClientOptions: ClientOptions = {
|
||||
hostname: "securedomain.com",
|
||||
secure: true,
|
||||
port: 443,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
|
||||
let socket = create(secureClientOptions);
|
||||
|
||||
socket.on("connect", () => {
|
||||
console.log("CONNECTED");
|
||||
});
|
||||
|
||||
// Listen to an event called 'rand' from the server
|
||||
socket.on("rand", (num: any) => {
|
||||
console.log("RANDOM: " + num);
|
||||
});
|
||||
|
||||
const options: ClientOptions = {
|
||||
path: "/socketcluster/",
|
||||
port: 8000,
|
||||
hostname: "127.0.0.1",
|
||||
autoConnect: true,
|
||||
secure: false,
|
||||
rejectUnauthorized: false,
|
||||
connectTimeout: 10000, // milliseconds
|
||||
ackTimeout: 10000, // milliseconds
|
||||
channelPrefix: null,
|
||||
disconnectOnUnload: true,
|
||||
multiplex: true,
|
||||
autoReconnectOptions: {
|
||||
initialDelay: 10000, // milliseconds
|
||||
randomness: 10000, // milliseconds
|
||||
multiplier: 1.5, // decimal
|
||||
maxDelay: 60000 // milliseconds
|
||||
},
|
||||
authEngine: null,
|
||||
codecEngine: null,
|
||||
subscriptionRetryOptions: {},
|
||||
query: {
|
||||
yourparam: "hello"
|
||||
}
|
||||
};
|
||||
socket = create(options);
|
||||
|
||||
socket.on("subscribe", channelname => {
|
||||
console.log("subscribe:" + channelname);
|
||||
});
|
||||
|
||||
socket.on("subscribeFail", channelname => {
|
||||
console.log("subscribeFail:" + channelname);
|
||||
});
|
||||
|
||||
socket.on("unsubscribe", channelname => {
|
||||
console.log("unsubscribe:" + channelname);
|
||||
});
|
||||
|
||||
socket.on("subscribeStateChange", data => {
|
||||
console.log("subscribeStateChange:" + JSON.stringify(data));
|
||||
});
|
||||
|
||||
socket.on("message", data => {
|
||||
console.log("message:" + data);
|
||||
});
|
||||
|
||||
const channels = socket.channels;
|
||||
const testChannel = channels["test"];
|
||||
const state = testChannel.getState();
|
||||
|
||||
destroy(socket);
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"lib/scclientsocket.d.ts",
|
||||
"socketcluster-client-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// Type definitions for socketcluster-server 13.1
|
||||
// Project: https://github.com/SocketCluster/socketcluster-server
|
||||
// Definitions by: Daniel Rose <https://github.com/DanielRose>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
import { Server } from "http";
|
||||
|
||||
export import SCServer = require("./scserver");
|
||||
export import SCServerSocket = require("./scserversocket");
|
||||
|
||||
export function listen(port?: number, options?: SCServer.SCServerOptions, listeningListener?: () => void): SCServer;
|
||||
export function listen(port?: number, listeningListener?: () => void): SCServer;
|
||||
|
||||
export function attach(server: Server, options?: SCServer.SCServerOptions): SCServer;
|
||||
+315
@@ -0,0 +1,315 @@
|
||||
import { EventEmitter } from "events";
|
||||
import { Secret } from "jsonwebtoken";
|
||||
import { ServerOptions } from "https";
|
||||
import { IncomingMessage, Server } from "http";
|
||||
import { SCAuthEngine } from "sc-auth";
|
||||
import { SCExchange } from "sc-broker-cluster";
|
||||
import WebSocket = require("ws");
|
||||
|
||||
import SCServerSocket = require("./scserversocket");
|
||||
|
||||
declare class SCServer extends EventEmitter {
|
||||
readonly MIDDLEWARE_HANDSHAKE_WS: "handshakeWS";
|
||||
readonly MIDDLEWARE_HANDSHAKE_SC: "handshakeSC";
|
||||
readonly MIDDLEWARE_AUTHENTICATE: "authenticate";
|
||||
readonly MIDDLEWARE_SUBSCRIBE: "subscribe";
|
||||
readonly MIDDLEWARE_PUBLISH_IN: "publishIn";
|
||||
readonly MIDDLEWARE_PUBLISH_OUT: "publishOut";
|
||||
readonly MIDDLEWARE_EMIT: "emit";
|
||||
|
||||
options: SCServer.SCServerOptions;
|
||||
exchange: SCExchange;
|
||||
|
||||
clients: {
|
||||
[id: string]: SCServerSocket;
|
||||
};
|
||||
clientsCount: number;
|
||||
|
||||
pendingClients: {
|
||||
[id: string]: SCServerSocket;
|
||||
};
|
||||
pendingClientsCount: number;
|
||||
|
||||
constructor(options?: SCServer.SCServerOptions);
|
||||
|
||||
on(event: "connection", listener: SCServer.connectionListenerFunction): this;
|
||||
|
||||
addMiddleware(type: "handshakeWS", middlewareFn: (req: IncomingMessage, next: SCServer.nextMiddlewareFunction) => void): void;
|
||||
addMiddleware(type: "handshakeSC", middlewareFn: (req: SCServer.HandshakeSCRequest, next: SCServer.nextHandshakeSCMiddlewareFunction) => void): void;
|
||||
addMiddleware(type: "authenticate", middlewareFn: (req: SCServer.AuthenticateRequest, next: SCServer.nextAuthenticateMiddlewareFunction) => void): void;
|
||||
addMiddleware(type: "subscribe", middlewareFn: (req: SCServer.SubscribeRequest, next: SCServer.nextMiddlewareFunction) => void): void;
|
||||
addMiddleware(type: "publishIn", middlewareFn: (req: SCServer.PublishInRequest, next: SCServer.nextMiddlewareFunction) => void): void;
|
||||
addMiddleware(type: "publishOut", middlewareFn: (req: SCServer.PublishOutRequest, next: SCServer.nextMiddlewareFunction) => void): void;
|
||||
addMiddleware(type: "emit", middlewareFn: (req: SCServer.EmitRequest, next: SCServer.nextMiddlewareFunction) => void): void;
|
||||
|
||||
setAuthEngine(authEngine: SCAuthEngine): void;
|
||||
setCodecEngine(codecEngine: SCServer.SCCodecEngine): void;
|
||||
}
|
||||
|
||||
export = SCServer;
|
||||
|
||||
declare namespace SCServer {
|
||||
interface AuthToken {
|
||||
[x: string]: any;
|
||||
}
|
||||
|
||||
interface SCServerOptions {
|
||||
// The port on which to listen for outside connections/requests
|
||||
port?: number;
|
||||
|
||||
// Number of worker processes
|
||||
workers?: number;
|
||||
|
||||
// Number of broker processes
|
||||
brokers?: number;
|
||||
|
||||
// Should be either 'dev' or 'prod' - This affects the shutdown procedure
|
||||
// when a 'SIGUSR2' signal is received by master. In 'dev', a SIGUSR2 will
|
||||
// trigger an immediate shutdown of workers. In 'prod' workers will
|
||||
// be terminated progressively in accordance with processTermTimeout.
|
||||
environment?: string;
|
||||
|
||||
// Setting this to true will cause the master process to shut down when
|
||||
// it receives a SIGUSR2 signal (instead of just the workers).
|
||||
// If you're using nodemon, set this to true.
|
||||
killMasterOnSignal?: boolean;
|
||||
|
||||
// A unique name for your app (this is used internally for
|
||||
// various things such as the directory name in which to store socket
|
||||
// file descriptors) - If you don't provide an appName, SC will
|
||||
// generate a random one (UUID v4)
|
||||
appName?: string;
|
||||
|
||||
// This can be the name of an npm module or a path to a Node.js module
|
||||
// to use as the WebSocket server engine.
|
||||
// You can now set this to 'sc-uws' for a massive speedup of at least 2x!
|
||||
wsEngine?: string;
|
||||
|
||||
// An ID to associate with this specific instance of SC
|
||||
// this may be useful if you are running an SC app on multiple
|
||||
// hosts - You can access the instanceId from the Broker object
|
||||
// (inside brokerController) - If you don't provide an instanceId,
|
||||
// SC will generate a random one (UUID v4)
|
||||
instanceId?: string;
|
||||
|
||||
// A key which various SC processes will use to interact with
|
||||
// scBroker broker processes securely, defaults to a 256 bits
|
||||
// cryptographically random hex string
|
||||
secretKey?: string;
|
||||
|
||||
// The key which SC will use to encrypt/decrypt authTokens, defaults
|
||||
// to a 256 bits cryptographically random hex string
|
||||
// The default JWT algorithm used is 'HS256'.
|
||||
// If you want to use RSA or ECDSA, you should provide a authPrivateKey
|
||||
// and authPublicKey instead of authKey.
|
||||
authKey?: Secret;
|
||||
|
||||
// perMessageDeflate compression. Note that this option is passed directly to the wsEngine's
|
||||
// Server object. So if you're using 'ws' as the engine, you can pass an object instead of
|
||||
// a boolean. Search for perMessageDeflate here:
|
||||
// https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketserveroptions-callback
|
||||
// Note that by default, per-message deflate only kicks in for messages > 1024 bytes.
|
||||
perMessageDeflate?: boolean;
|
||||
|
||||
// If using an RSA or ECDSA algorithm to sign the authToken, you will need
|
||||
// to provide an authPrivateKey and authPublicKey in PEM format (string or Buffer).
|
||||
authPrivateKey?: Secret;
|
||||
authPublicKey?: Secret;
|
||||
|
||||
// The default expiry for auth tokens in seconds
|
||||
authDefaultExpiry?: number;
|
||||
|
||||
// The algorithm to use to sign and verify JWT tokens.
|
||||
authAlgorithm?: string;
|
||||
|
||||
// Crash workers when an error happens - This is the most sensible default
|
||||
crashWorkerOnError?: boolean;
|
||||
|
||||
// Reboot workers when they crash - This is a necessity
|
||||
// in production but can be turned off for debugging
|
||||
rebootWorkerOnCrash?: boolean;
|
||||
|
||||
// Kill/respawn a worker process if its memory consumption exceeds this
|
||||
// threshold (in bytes) - If this is null (default), this behavior
|
||||
// will be switched off
|
||||
killWorkerMemoryThreshold?: number;
|
||||
|
||||
// Can be 'http' or 'https'
|
||||
protocol?: "http" | "https";
|
||||
|
||||
// This is the same as the object provided to Node.js's https server
|
||||
protocolOptions?: ServerOptions;
|
||||
|
||||
// A log level of 3 will log everything, 2 will show notices and errors,
|
||||
// 1 will only log errors, 0 will log nothing
|
||||
logLevel?: 0 | 1 | 2 | 3;
|
||||
|
||||
// In milliseconds, how long a client has to connect to SC before timing out
|
||||
connectTimeout?: number;
|
||||
|
||||
// In milliseconds - If the socket handshake hasn't been completed before
|
||||
// this timeout is reached, the new connection attempt will be terminated.
|
||||
handshakeTimeout?: number;
|
||||
|
||||
// In milliseconds, the timeout for calling res(err, data) when
|
||||
// your emit() call expects an ACK response from the other side
|
||||
// (when callback is provided to emit)
|
||||
ackTimeout?: number;
|
||||
|
||||
// In milliseconds, the timeout for calling res(err, data) when
|
||||
// your sendToWorker, sendToBroker or sendToMaster (IPC) call
|
||||
// expects an ACK response from the other process
|
||||
// (when callback is provided)
|
||||
ipcAckTimeout?: number;
|
||||
|
||||
// In milliseconds - If the socket cannot upgrade transport
|
||||
// within this period, it will stop trying
|
||||
socketUpgradeTimeout?: number;
|
||||
|
||||
// Origins which are allowed to connect to the real-time scServer
|
||||
origins?: string;
|
||||
|
||||
// The maximum number of unique channels which a single
|
||||
// socket can subscribe to
|
||||
socketChannelLimit?: number;
|
||||
|
||||
// The interval in milliseconds on which to
|
||||
// send a ping to the client to check that
|
||||
// it is still alive
|
||||
pingInterval?: number;
|
||||
|
||||
// How many milliseconds to wait without receiving a ping
|
||||
// before closing the socket
|
||||
pingTimeout?: number;
|
||||
|
||||
// Maximum amount of milliseconds to wait before force-killing
|
||||
// a process after it was passed a 'SIGTERM' or 'SIGUSR2' signal
|
||||
processTermTimeout?: number;
|
||||
|
||||
// Whether or not errors from child processes (workers and brokers)
|
||||
// should be passed to the current master process
|
||||
propagateErrors?: boolean;
|
||||
|
||||
// Whether or not warnings from child processes (workers and brokers)
|
||||
// should be passed to the current master process
|
||||
propagateWarnings?: number;
|
||||
|
||||
// Whether or not a 'warning' event should be emitted (and logged to console)
|
||||
// whenever an action is blocked by a middleware function
|
||||
middlewareEmitWarnings?: number;
|
||||
|
||||
// Lets you specify a host name to bind to - Defaults to
|
||||
// 127.0.0.1 (localhost)
|
||||
host?: string;
|
||||
|
||||
// The path to a file used to bootstrap worker processes
|
||||
workerController?: string;
|
||||
|
||||
// The path to a file used to bootstrap broker processes
|
||||
brokerController?: string;
|
||||
|
||||
// The path to a file used to bootstrap the workerCluster process
|
||||
workerClusterController?: string;
|
||||
|
||||
// By default, SC will reboot all workers when it receives a 'SIGUSR2' signal -
|
||||
// This can be used for updating workers with fresh source code in production
|
||||
rebootOnSignal?: boolean;
|
||||
|
||||
// If you run your master process (server.js) as super user, this option
|
||||
// lets you downgrade worker and broker processes to run under
|
||||
// the specified user (with fewer permissions than master) - You can provide
|
||||
// a Linux UID or username
|
||||
downgradeToUser?: number | string;
|
||||
|
||||
// The URL path reserved by SocketCluster clients to interact with the server
|
||||
path?: string;
|
||||
|
||||
// The root directory in which to store your socket files in Linux.
|
||||
socketRoot?: string;
|
||||
|
||||
// Defaults to "rr", but can be set to "none"
|
||||
schedulingPolicy?: "rr" | "none";
|
||||
|
||||
// Whether or not clients are allowed to publish messages to channels
|
||||
allowClientPublish?: boolean;
|
||||
|
||||
// This option is passed to the Node.js HTTP server if provided
|
||||
tcpSynBacklog?: number;
|
||||
|
||||
// SC keeps track of request per minutes internally - This allows you to change
|
||||
// how often this gets updated
|
||||
workerStatusInterval?: number;
|
||||
|
||||
// This allows you to batch multiple messages together when passing them across
|
||||
// message brokers. This may improve the efficiency of your pub/sub operations.
|
||||
// This value is in milliseconds. 5 is generally a safe value to set this to.
|
||||
pubSubBatchDuration?: number;
|
||||
|
||||
// The default clustering/brokering engine (Node.js module name) which provides the
|
||||
// SCWorker.exchange object and manages brokers behind the scenes.
|
||||
// You shouldn't need to change this unless you want to build your own
|
||||
// process clustering engine (which is difficult to do).
|
||||
brokerEngine?: string;
|
||||
|
||||
wsEngineServerOptions?: WebSocket.ClientOptions;
|
||||
maxPayload?: number;
|
||||
pingTimeoutDisabled?: boolean;
|
||||
authSignAsync?: boolean;
|
||||
authVerifyAsync?: boolean;
|
||||
httpServer?: Server;
|
||||
}
|
||||
|
||||
interface SCServerSocketStatus {
|
||||
id: string;
|
||||
pingTimeout: number;
|
||||
}
|
||||
|
||||
interface HandshakeSCRequest {
|
||||
socket: SCServerSocket;
|
||||
}
|
||||
|
||||
interface AuthenticateRequest {
|
||||
socket: SCServerSocket;
|
||||
authToken: AuthToken;
|
||||
}
|
||||
|
||||
interface SubscribeRequest {
|
||||
socket: SCServerSocket;
|
||||
authTokenExpiredError?: Error;
|
||||
channel?: string;
|
||||
waitForAuth?: boolean;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
interface PublishInRequest {
|
||||
socket: SCServerSocket;
|
||||
authTokenExpiredError?: Error;
|
||||
channel?: string;
|
||||
data?: any;
|
||||
ackData?: any;
|
||||
}
|
||||
|
||||
interface PublishOutRequest {
|
||||
socket: SCServerSocket;
|
||||
channel?: string;
|
||||
data?: any;
|
||||
useCache?: boolean;
|
||||
}
|
||||
|
||||
interface EmitRequest {
|
||||
socket: SCServerSocket;
|
||||
authTokenExpiredError?: Error;
|
||||
event: string;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
type nextMiddlewareFunction = (error?: true | string | Error) => void;
|
||||
type nextHandshakeSCMiddlewareFunction = (error?: true | string | Error | null, statusCode?: number) => void;
|
||||
type nextAuthenticateMiddlewareFunction = (error?: true | string | Error | null, isBadToken?: boolean) => void;
|
||||
type connectionListenerFunction = (scSocket: SCServerSocket, serverSocketStatus: SCServerSocketStatus) => void;
|
||||
|
||||
interface SCCodecEngine {
|
||||
decode: (input: any) => any;
|
||||
ncode: (object: any) => any;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import Emitter = require("component-emitter");
|
||||
import { IncomingMessage } from "http";
|
||||
import { SCExchange } from "sc-broker-cluster";
|
||||
import { SignOptions } from "jsonwebtoken";
|
||||
import WebSocket = require("ws");
|
||||
|
||||
import SCServer = require("./scserver");
|
||||
|
||||
declare class SCServerSocket extends Emitter {
|
||||
readonly CONNECTING: "connecting";
|
||||
readonly OPEN: "open";
|
||||
readonly CLOSED: "closed";
|
||||
|
||||
readonly AUTHENTICATED: "authenticated";
|
||||
readonly UNAUTHENTICATED: "unauthenticated";
|
||||
|
||||
id: string;
|
||||
request: IncomingMessage;
|
||||
|
||||
remoteAddress: string;
|
||||
remoteFamily: string;
|
||||
remotePort: number;
|
||||
|
||||
exchange: SCExchange;
|
||||
|
||||
state: "connecting" | "open" | "closed";
|
||||
authState: "authenticated" | "unauthenticated";
|
||||
authToken?: SCServer.AuthToken;
|
||||
|
||||
constructor(id: string, server: SCServer, socket: WebSocket);
|
||||
|
||||
getState(): "connecting" | "open" | "closed";
|
||||
disconnect(code?: number, data?: any): void;
|
||||
send(data: any, options: { mask?: boolean; binary?: boolean; compress?: boolean; fin?: boolean }): void;
|
||||
getAuthToken(): SCServer.AuthToken;
|
||||
setAuthToken(data: SCServer.AuthToken, options?: SignOptions): void;
|
||||
deauthenticate(): void;
|
||||
kickOut(channel?: string, message?: string, callback?: () => void): void;
|
||||
subscriptions(): string[];
|
||||
isSubscribed(channel?: string): boolean;
|
||||
}
|
||||
|
||||
export = SCServerSocket;
|
||||
@@ -0,0 +1,39 @@
|
||||
// Adapted from README
|
||||
|
||||
// Using with basic http(s) module (example)
|
||||
|
||||
import http = require("http");
|
||||
import * as socketClusterServer from "socketcluster-server";
|
||||
|
||||
let httpServer = http.createServer();
|
||||
let scServer = socketClusterServer.attach(httpServer);
|
||||
|
||||
scServer.on("connection", socket => {
|
||||
// ... Handle new socket connections here
|
||||
});
|
||||
|
||||
httpServer.listen(8000);
|
||||
|
||||
// Using with Express (example)
|
||||
|
||||
import serveStatic = require("serve-static");
|
||||
import path = require("path");
|
||||
import express = require("express");
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use(serveStatic(path.resolve(__dirname, "public")));
|
||||
|
||||
httpServer = http.createServer();
|
||||
|
||||
// Attach express to our httpServer
|
||||
httpServer.on("request", app);
|
||||
|
||||
// Attach socketcluster-server to our httpServer
|
||||
scServer = socketClusterServer.attach(httpServer);
|
||||
|
||||
scServer.on("connection", socket => {
|
||||
// ... Handle new socket connections here
|
||||
});
|
||||
|
||||
httpServer.listen(8000);
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"scserver.d.ts",
|
||||
"scserversocket.d.ts",
|
||||
"socketcluster-server-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json"
|
||||
}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
import { PathLike } from "fs";
|
||||
|
||||
export function fileExists(filePath: PathLike, callback: (exists: boolean) => void): void;
|
||||
|
||||
export function waitForFile(
|
||||
filePath: PathLike,
|
||||
checkInterval: number,
|
||||
startTime: number,
|
||||
maxWaitDuration: number,
|
||||
timeoutErrorMessage?: string
|
||||
): Promise<void>;
|
||||
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
// Type definitions for socketcluster 14.0
|
||||
// Project: https://github.com/SocketCluster/socketcluster
|
||||
// Definitions by: Daniel Rose <https://github.com/DanielRose>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.4
|
||||
|
||||
import { EventEmitter } from "events";
|
||||
import { SCServer } from "socketcluster-server";
|
||||
import { ChildProcess } from "child_process";
|
||||
|
||||
interface WorkerStartInfo {
|
||||
id: number;
|
||||
pid: number;
|
||||
respawn: boolean;
|
||||
}
|
||||
|
||||
interface WorkerClusterStartInfo {
|
||||
pid: number;
|
||||
childProcess: ChildProcess;
|
||||
}
|
||||
|
||||
interface WorkerClusterReadyInfo {
|
||||
pid: number;
|
||||
childProcess: ChildProcess;
|
||||
}
|
||||
|
||||
interface WorkerClusterExitInfo {
|
||||
pid: number;
|
||||
code: number;
|
||||
signal: string;
|
||||
childProcess: ChildProcess;
|
||||
}
|
||||
|
||||
export = SocketCluster;
|
||||
|
||||
declare class SocketCluster extends EventEmitter {
|
||||
readonly EVENT_FAIL: "fail";
|
||||
readonly EVENT_WARNING: "warning";
|
||||
readonly EVENT_READY: "ready";
|
||||
readonly EVENT_WORKER_START: "workerStart";
|
||||
readonly EVENT_WORKER_EXIT: "workerExit";
|
||||
readonly EVENT_BROKER_START: "brokerStart";
|
||||
readonly EVENT_BROKER_EXIT: "brokerExit";
|
||||
readonly EVENT_WORKER_CLUSTER_START: "workerClusterStart";
|
||||
readonly EVENT_WORKER_CLUSTER_READY: "workerClusterReady";
|
||||
readonly EVENT_WORKER_CLUSTER_EXIT: "workerClusterExit";
|
||||
|
||||
options: SCServer.SCServerOptions;
|
||||
|
||||
constructor(options?: SCServer.SCServerOptions);
|
||||
|
||||
on(event: "fail", listener: (err: Error) => void): this;
|
||||
on(event: "warning", listener: (warning: Error) => void): this;
|
||||
on(event: "ready", listener: () => void): this;
|
||||
on(event: "workerStart", listener: (workerInfo: WorkerStartInfo) => void): this;
|
||||
on(event: "workerExit", listener: (workerInfo: SocketCluster.WorkerExitInfo) => void): this;
|
||||
on(event: "brokerStart", listener: (brokerInfo: SocketCluster.BrokerStartInfo) => void): this;
|
||||
on(event: "brokerExit", listener: (brokerInfo: SocketCluster.BrokerExitInfo) => void): this;
|
||||
on(event: "workerClusterStart", listener: (workerClusterInfo: WorkerClusterStartInfo) => void): this;
|
||||
on(event: "workerClusterReady", listener: (workerClusterInfo: WorkerClusterReadyInfo) => void): this;
|
||||
on(event: "workerClusterExit", listener: (workerClusterInfo: WorkerClusterExitInfo) => void): this;
|
||||
}
|
||||
|
||||
declare namespace SocketCluster {
|
||||
interface WorkerExitInfo {
|
||||
id: number;
|
||||
pid: number;
|
||||
code: number;
|
||||
signal: string;
|
||||
}
|
||||
|
||||
interface BrokerStartInfo {
|
||||
id: number;
|
||||
pid: number;
|
||||
respawn: boolean;
|
||||
}
|
||||
|
||||
interface BrokerExitInfo {
|
||||
id: number;
|
||||
pid: number;
|
||||
code: number;
|
||||
signal: string;
|
||||
}
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import SCBroker = require("sc-broker-cluster/scbroker");
|
||||
|
||||
export = SCBroker;
|
||||
Vendored
+63
@@ -0,0 +1,63 @@
|
||||
import { EventEmitter } from "events";
|
||||
import { Server as httpServer } from "http";
|
||||
import { Server as httpsServer } from "https";
|
||||
import { SCServer, SCServerSocket } from "socketcluster-server";
|
||||
import { SCAuthEngine } from "sc-auth";
|
||||
import { SCExchange } from "sc-broker-cluster";
|
||||
|
||||
export = SCWorker;
|
||||
|
||||
type middlewareFunction = (options: SCServer.SCServerOptions, next: (error?: string | Error) => void) => void;
|
||||
|
||||
declare class SCWorker extends EventEmitter {
|
||||
readonly EVENT_ERROR: "error";
|
||||
readonly EVENT_WARNING: "warning";
|
||||
readonly EVENT_EXIT: "exit";
|
||||
readonly EVENT_READY: "ready";
|
||||
readonly EVENT_CONNECTION: "connection";
|
||||
|
||||
readonly MIDDLEWARE_START: "start";
|
||||
|
||||
id: number;
|
||||
isLeader: boolean;
|
||||
options: SCServer.SCServerOptions;
|
||||
httpServer: httpServer | httpsServer;
|
||||
scServer: SCServer;
|
||||
exchange: SCExchange;
|
||||
auth: SCAuthEngine;
|
||||
|
||||
constructor(options?: SCServer.SCServerOptions);
|
||||
|
||||
run(): void;
|
||||
|
||||
getSCServer(): SCServer;
|
||||
getHTTPServer(): httpServer | httpsServer;
|
||||
getSocketPath(): string;
|
||||
|
||||
setAuthEngine(authEngine: SCAuthEngine): void;
|
||||
setCodecEngine(codecEngine: SCServer.SCCodecEngine): void;
|
||||
|
||||
open(): void;
|
||||
close(callback?: () => void): void;
|
||||
|
||||
addMiddleware(type: "start", middlewareFn: middlewareFunction): void;
|
||||
removeMiddleware(type: "start", middlewareFn: middlewareFunction): void;
|
||||
|
||||
startHTTPServer(): void;
|
||||
start(): Promise<void>;
|
||||
|
||||
getStatus(): {
|
||||
clientCount: any;
|
||||
httpRPM: number;
|
||||
wsRPM: number;
|
||||
};
|
||||
|
||||
sendToMaster(data: any, callback: (err: Error | null, data: any) => void): void;
|
||||
respondToMaster(err: Error | null, data: any, rid: number): void;
|
||||
|
||||
on(event: "connection", listener: (scSocket: SCServerSocket) => void): this;
|
||||
on(event: "ready", listener: () => void): this;
|
||||
on(event: "error", listener: (err: Error) => void): this;
|
||||
on(event: "warning", listener: (warning: Error) => void): this;
|
||||
on(event: "masterMessage", listener: (data: any, respond: (err: Error | null, responseData: any) => void) => void): this;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import * as fsutil from "socketcluster/fsutil";
|
||||
import SocketCluster = require("socketcluster");
|
||||
import { SCServer } from "socketcluster-server";
|
||||
import { ChildProcess } from "child_process";
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
/// SocketCluster tests
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const options: SCServer.SCServerOptions = { port: 80 };
|
||||
|
||||
let sc = new SocketCluster();
|
||||
sc = new SocketCluster(options);
|
||||
sc.options = { environment: "prod" };
|
||||
|
||||
sc.on(sc.EVENT_FAIL, err => {
|
||||
const error: Error = err;
|
||||
});
|
||||
sc.on(sc.EVENT_WARNING, warning => {
|
||||
const warn: Error = warning;
|
||||
});
|
||||
|
||||
sc.on(sc.EVENT_READY, () => {});
|
||||
|
||||
sc.on(sc.EVENT_WORKER_START, workerInfo => {
|
||||
const id: number = workerInfo.id;
|
||||
const pid: number = workerInfo.pid;
|
||||
const respawn: boolean = workerInfo.respawn;
|
||||
});
|
||||
sc.on(sc.EVENT_WORKER_EXIT, workerInfo => {
|
||||
const id: number = workerInfo.id;
|
||||
const pid: number = workerInfo.pid;
|
||||
const code: number = workerInfo.code;
|
||||
const signal: string = workerInfo.signal;
|
||||
});
|
||||
|
||||
sc.on(sc.EVENT_BROKER_START, brokerInfo => {
|
||||
const id: number = brokerInfo.id;
|
||||
const pid: number = brokerInfo.pid;
|
||||
const respawn: boolean = brokerInfo.respawn;
|
||||
});
|
||||
sc.on(sc.EVENT_BROKER_EXIT, brokerInfo => {
|
||||
const id: number = brokerInfo.id;
|
||||
const pid: number = brokerInfo.pid;
|
||||
const code: number = brokerInfo.code;
|
||||
const signal: string = brokerInfo.signal;
|
||||
});
|
||||
|
||||
sc.on(sc.EVENT_WORKER_CLUSTER_START, workerClusterInfo => {
|
||||
const pid: number = workerClusterInfo.pid;
|
||||
const childProcess: ChildProcess = workerClusterInfo.childProcess;
|
||||
});
|
||||
sc.on(sc.EVENT_WORKER_CLUSTER_READY, workerClusterInfo => {
|
||||
const pid: number = workerClusterInfo.pid;
|
||||
const childProcess: ChildProcess = workerClusterInfo.childProcess;
|
||||
});
|
||||
sc.on(sc.EVENT_WORKER_CLUSTER_EXIT, workerClusterInfo => {
|
||||
const pid: number = workerClusterInfo.pid;
|
||||
const code: number = workerClusterInfo.code;
|
||||
const signal: string = workerClusterInfo.signal;
|
||||
const childProcess: ChildProcess = workerClusterInfo.childProcess;
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
/// fsutil tests
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
fsutil.fileExists("/path/to/folder", err => {});
|
||||
fsutil.fileExists(Buffer.from(""), err => {});
|
||||
|
||||
const pathPromise: Promise<void> = fsutil.waitForFile("/path/to/folder", 100, 0, 100);
|
||||
const bufferPromise: Promise<void> = fsutil.waitForFile(Buffer.from(""), 0, 0, 0, "timeout");
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"fsutil.d.ts",
|
||||
"scbroker.d.ts",
|
||||
"scworker.d.ts",
|
||||
"socketcluster-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "dtslint/dt.json"
|
||||
}
|
||||
Reference in New Issue
Block a user