Skip to content

Commit 96a9f41

Browse files
authored
chore: internal typing improvements (#1708)
1 parent a22fd2d commit 96a9f41

File tree

7 files changed

+93
-65
lines changed

7 files changed

+93
-65
lines changed

lib/DataHandler.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,29 @@ const debug = Debug("dataHandler");
1010

1111
type ReplyData = string | Buffer | number | Array<string | Buffer | number>;
1212

13-
interface Condition {
13+
export interface Condition {
1414
select: number;
15-
auth: string;
15+
auth?: string | [string, string];
1616
subscriber: false | SubscriptionSet;
1717
}
1818

19-
interface DataHandledable extends EventEmitter {
19+
export type FlushQueueOptions = {
20+
offlineQueue?: boolean;
21+
commandQueue?: boolean;
22+
};
23+
24+
export interface DataHandledable extends EventEmitter {
2025
stream: NetStream;
2126
status: string;
22-
condition: Condition;
27+
condition: Condition | null;
2328
commandQueue: Deque<CommandItem>;
2429

2530
disconnect(reconnect: boolean): void;
26-
recoverFromFatalError(commandError: Error, err: Error, options: any): void;
31+
recoverFromFatalError(
32+
commandError: Error,
33+
err: Error,
34+
options: FlushQueueOptions
35+
): void;
2736
handleReconnection(err: Error, item: CommandItem): void;
2837
}
2938

lib/Redis.ts

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { EventEmitter } from "events";
33
import asCallback from "standard-as-callback";
44
import Cluster from "./cluster";
55
import Command from "./Command";
6+
import { DataHandledable, FlushQueueOptions, Condition } from "./DataHandler";
67
import { StandaloneConnector } from "./connectors";
78
import AbstractConnector from "./connectors/AbstractConnector";
89
import SentinelConnector from "./connectors/SentinelConnector";
@@ -60,7 +61,7 @@ type RedisStatus =
6061
* }
6162
* ```
6263
*/
63-
class Redis extends Commander {
64+
class Redis extends Commander implements DataHandledable {
6465
static Cluster = Cluster;
6566
static Command = Command;
6667
/**
@@ -89,14 +90,18 @@ class Redis extends Commander {
8990
*/
9091
isCluster = false;
9192

93+
/**
94+
* @ignore
95+
*/
96+
condition: Condition | null;
97+
98+
/**
99+
* @ignore
100+
*/
101+
commandQueue: Deque<CommandItem>;
102+
92103
private connector: AbstractConnector;
93104
private reconnectTimeout: ReturnType<typeof setTimeout> | null = null;
94-
private condition: {
95-
select: number;
96-
auth?: string | [string, string];
97-
subscriber: boolean;
98-
};
99-
private commandQueue: Deque<CommandItem>;
100105
private offlineQueue: Deque;
101106
private connectionEpoch = 0;
102107
private retryAttempts = 0;
@@ -220,9 +225,11 @@ class Redis extends Commander {
220225

221226
// Node ignores setKeepAlive before connect, therefore we wait for the event:
222227
// https://github.com/nodejs/node/issues/31663
223-
if (typeof options.keepAlive === 'number') {
228+
if (typeof options.keepAlive === "number") {
224229
if (stream.connecting) {
225-
stream.once(CONNECT_EVENT, () => stream.setKeepAlive(true, options.keepAlive));
230+
stream.once(CONNECT_EVENT, () => {
231+
stream.setKeepAlive(true, options.keepAlive);
232+
});
226233
} else {
227234
stream.setKeepAlive(true, options.keepAlive);
228235
}
@@ -344,10 +351,10 @@ class Redis extends Commander {
344351
* One of `"normal"`, `"subscriber"`, or `"monitor"`. When the connection is
345352
* not in `"normal"` mode, certain commands are not allowed.
346353
*/
347-
get mode(): "normal" | "subscriber" | "monitor" {
354+
get mode(): "normal" | "subscriber" | "monitor" {
348355
return this.options.monitor
349356
? "monitor"
350-
: this.condition && this.condition.subscriber
357+
: this.condition?.subscriber
351358
? "subscriber"
352359
: "normal";
353360
}
@@ -421,7 +428,7 @@ class Redis extends Commander {
421428
return command.promise;
422429
}
423430
if (
424-
this.condition.subscriber &&
431+
this.condition?.subscriber &&
425432
!Command.checkFlag("VALID_IN_SUBSCRIBER_MODE", command.name)
426433
) {
427434
command.reject(
@@ -491,7 +498,7 @@ class Redis extends Commander {
491498
debug(
492499
"write command[%s]: %d -> %s(%o)",
493500
this._getDescription(),
494-
this.condition.select,
501+
this.condition?.select,
495502
command.name,
496503
command.args
497504
);
@@ -600,45 +607,22 @@ class Redis extends Commander {
600607
}
601608

602609
/**
603-
* Get description of the connection. Used for debugging.
610+
* @ignore
604611
*/
605-
private _getDescription() {
606-
let description;
607-
if ("path" in this.options && this.options.path) {
608-
description = this.options.path;
609-
} else if (
610-
this.stream &&
611-
this.stream.remoteAddress &&
612-
this.stream.remotePort
613-
) {
614-
description = this.stream.remoteAddress + ":" + this.stream.remotePort;
615-
} else if ("host" in this.options && this.options.host) {
616-
description = this.options.host + ":" + this.options.port;
617-
} else {
618-
// Unexpected
619-
description = "";
620-
}
621-
if (this.options.connectionName) {
622-
description += ` (${this.options.connectionName})`;
623-
}
624-
return description;
625-
}
626-
627-
private resetCommandQueue() {
628-
this.commandQueue = new Deque();
629-
}
630-
631-
private resetOfflineQueue() {
632-
this.offlineQueue = new Deque();
633-
}
634-
635-
private recoverFromFatalError(commandError, err: Error | null, options) {
612+
recoverFromFatalError(
613+
_commandError: Error,
614+
err: Error,
615+
options: FlushQueueOptions
616+
) {
636617
this.flushQueue(err, options);
637618
this.silentEmit("error", err);
638619
this.disconnect(true);
639620
}
640621

641-
private handleReconnection(err: Error, item: CommandItem) {
622+
/**
623+
* @ignore
624+
*/
625+
handleReconnection(err: Error, item: CommandItem) {
642626
let needReconnect: ReturnType<ReconnectOnError> = false;
643627
if (this.options.reconnectOnError) {
644628
needReconnect = this.options.reconnectOnError(err);
@@ -657,7 +641,7 @@ class Redis extends Commander {
657641
this.disconnect(true);
658642
}
659643
if (
660-
this.condition.select !== item.select &&
644+
this.condition?.select !== item.select &&
661645
item.command.name !== "select"
662646
) {
663647
this.select(item.select);
@@ -671,6 +655,39 @@ class Redis extends Commander {
671655
}
672656
}
673657

658+
/**
659+
* Get description of the connection. Used for debugging.
660+
*/
661+
private _getDescription() {
662+
let description;
663+
if ("path" in this.options && this.options.path) {
664+
description = this.options.path;
665+
} else if (
666+
this.stream &&
667+
this.stream.remoteAddress &&
668+
this.stream.remotePort
669+
) {
670+
description = this.stream.remoteAddress + ":" + this.stream.remotePort;
671+
} else if ("host" in this.options && this.options.host) {
672+
description = this.options.host + ":" + this.options.port;
673+
} else {
674+
// Unexpected
675+
description = "";
676+
}
677+
if (this.options.connectionName) {
678+
description += ` (${this.options.connectionName})`;
679+
}
680+
return description;
681+
}
682+
683+
private resetCommandQueue() {
684+
this.commandQueue = new Deque();
685+
}
686+
687+
private resetOfflineQueue() {
688+
this.offlineQueue = new Deque();
689+
}
690+
674691
private parseOptions(...args: unknown[]) {
675692
const options: Record<string, unknown> = {};
676693
let isTls = false;
@@ -744,7 +761,7 @@ class Redis extends Commander {
744761
* @param error The error object to send to the commands
745762
* @param options options
746763
*/
747-
private flushQueue(error: Error, options?: RedisOptions) {
764+
private flushQueue(error: Error, options?: FlushQueueOptions) {
748765
options = defaults({}, options, {
749766
offlineQueue: true,
750767
commandQueue: true,

lib/ScanStream.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ interface Options extends ReadableOptions {
1010
}
1111

1212
/**
13-
* Convenient class to convert the process of scaning keys to a readable stream.
13+
* Convenient class to convert the process of scanning keys to a readable stream.
1414
*/
1515
export default class ScanStream extends Readable {
1616
private _redisCursor = "0";

lib/Script.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default class Script {
88

99
constructor(
1010
private lua: string,
11-
private numberOfKeys: number = null,
11+
private numberOfKeys: number | null = null,
1212
private keyPrefix: string = "",
1313
private readOnly: boolean = false
1414
) {

lib/cluster/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ class Cluster extends Commander {
564564
redis = nodes[0];
565565
}
566566
} else {
567-
let key;
567+
let key: string;
568568
if (to === "all") {
569569
key = sample(nodeKeys);
570570
} else if (to === "slave" && nodeKeys.length > 1) {

lib/redis/event_handler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ function abortError(command: Respondable) {
116116
function abortIncompletePipelines(commandQueue: Deque<CommandItem>) {
117117
let expectedIndex = 0;
118118
for (let i = 0; i < commandQueue.length; ) {
119-
const command = commandQueue.peekAt(i).command as Command;
119+
const command = commandQueue.peekAt(i)?.command as Command;
120120
const pipelineIndex = command.pipelineIndex;
121121
if (pipelineIndex === undefined || pipelineIndex === 0) {
122122
expectedIndex = 0;
@@ -135,7 +135,7 @@ function abortIncompletePipelines(commandQueue: Deque<CommandItem>) {
135135
// offline queue
136136
function abortTransactionFragments(commandQueue: Deque<CommandItem>) {
137137
for (let i = 0; i < commandQueue.length; ) {
138-
const command = commandQueue.peekAt(i).command as Command;
138+
const command = commandQueue.peekAt(i)?.command as Command;
139139
if (command.name === "multi") {
140140
break;
141141
}

lib/utils/index.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ export function convertBufferToString(value: any, encoding?: BufferEncoding) {
4343
* expect(output).to.eql([[null, 'a'], [null, 'b'], [new Error('c')], [null, 'd'])
4444
* ```
4545
*/
46-
export function wrapMultiResult(arr: unknown[] | null): unknown[][] {
46+
export function wrapMultiResult(arr: unknown[] | null): unknown[][] | null {
4747
// When using WATCH/EXEC transactions, the EXEC will return
4848
// a null instead of an array
4949
if (!arr) {
5050
return null;
5151
}
52-
const result = [];
52+
const result: unknown[][] = [];
5353
const length = arr.length;
5454
for (let i = 0; i < length; ++i) {
5555
const item = arr[i];
@@ -133,7 +133,7 @@ export function timeout<T>(
133133
export function convertObjectToArray<T>(
134134
obj: Record<string, T>
135135
): (string | T)[] {
136-
const result = [];
136+
const result: (string | T)[] = [];
137137
const keys = Object.keys(obj); // Object.entries requires node 7+
138138

139139
for (let i = 0, l = keys.length; i < l; i++) {
@@ -185,7 +185,7 @@ export function optimizeErrorStack(
185185
) {
186186
const stacks = friendlyStack.split("\n");
187187
let lines = "";
188-
let i;
188+
let i: number;
189189
for (i = 1; i < stacks.length; ++i) {
190190
if (stacks[i].indexOf(filterPath) === -1) {
191191
break;
@@ -194,8 +194,10 @@ export function optimizeErrorStack(
194194
for (let j = i; j < stacks.length; ++j) {
195195
lines += "\n" + stacks[j];
196196
}
197-
const pos = error.stack.indexOf("\n");
198-
error.stack = error.stack.slice(0, pos) + lines;
197+
if (error.stack) {
198+
const pos = error.stack.indexOf("\n");
199+
error.stack = error.stack.slice(0, pos) + lines;
200+
}
199201
return error;
200202
}
201203

@@ -278,7 +280,7 @@ export function resolveTLSProfile(options: TLSOptions): TLSOptions {
278280
export function sample<T>(array: T[], from = 0): T {
279281
const length = array.length;
280282
if (from >= length) {
281-
return;
283+
return null;
282284
}
283285
return array[from + Math.floor(Math.random() * (length - from))];
284286
}

0 commit comments

Comments
 (0)