Skip to content

Commit 4e7c44b

Browse files
committed
feat(json-pack): 🎸 decode command in streaming decoder
1 parent 3b29cab commit 4e7c44b

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/json-pack/resp/RespStreamingDecoder.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,29 @@ export class RespStreamingDecoder {
6767
}
6868
}
6969

70+
/**
71+
* Decode only one RESP command from the stream, if the value is not a
72+
* command, an error will be thrown.
73+
*
74+
* @returns Redis command and its arguments or `undefined` if there is
75+
* not enough data to decode.
76+
*/
77+
public readCmd(): [cmd: string, ...args: Uint8Array[]] | undefined {
78+
const reader = this.reader;
79+
if (reader.size() === 0) return undefined;
80+
const x = reader.x;
81+
try {
82+
const args = this.decoder.readCmd();
83+
reader.consume();
84+
return args;
85+
} catch (error) {
86+
if (error instanceof RangeError) {
87+
reader.x = x;
88+
return undefined;
89+
} else throw error;
90+
}
91+
}
92+
7093
/**
7194
* Skips one value from the stream. If `undefined` is returned, then
7295
* there is not enough data to skip or the stream is finished.

src/json-pack/resp/__tests__/RespStreamingDecoder.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {RespStreamingDecoder} from '../RespStreamingDecoder';
22
import {RespEncoder} from '../RespEncoder';
33
import {concatList} from '../../../util/buffers/concat';
44
import {documents} from '../../../__tests__/json-documents';
5+
import {utf8} from '../../../util/buffers/strings';
56

67
const encoder = new RespEncoder();
78

@@ -66,3 +67,11 @@ test('can stream 49 bytes at a time', () => {
6667
}
6768
expect(decoded).toEqual(docs);
6869
});
70+
71+
test('can decode a command', () => {
72+
const encoded = encoder.encodeCmd(['SET', 'foo', 'bar']);
73+
const decoder = new RespStreamingDecoder();
74+
decoder.push(encoded);
75+
const decoded = decoder.readCmd();
76+
expect(decoded).toEqual(['SET', utf8`foo`, utf8`bar`]);
77+
});

0 commit comments

Comments
 (0)