11import type * as types from "../shared/types.ts" ;
2+ import type { ProtocolEvents } from "../shared/types.ts" ;
23import {
34 ArrayReplyCode ,
45 AttributeReplyCode ,
@@ -19,12 +20,38 @@ import {
1920import { ErrorReplyError , NotImplementedError } from "../../errors.ts" ;
2021import { decoder } from "../../internal/encoding.ts" ;
2122import type { BufferedReadableStream } from "../../internal/buffered_readable_stream.ts" ;
23+ import type { TypedEventTarget } from "../../internal/typed_event_target.ts" ;
24+ import { dispatchEvent } from "../../internal/typed_event_target.ts" ;
25+
26+ export async function readOrEmitReply (
27+ readable : BufferedReadableStream ,
28+ eventTarget : TypedEventTarget < ProtocolEvents > ,
29+ returnUint8Arrays ?: boolean ,
30+ ) : Promise < types . RedisReply > {
31+ const line = await readable . readLine ( ) ;
32+ const code = line [ 0 ] ;
33+ if ( code === PushReplyCode ) {
34+ const reply = await parseArrayLikeReply ( line , readable , returnUint8Arrays ) ;
35+ dispatchEvent ( eventTarget , "push" , reply ?? [ ] ) ;
36+ return readOrEmitReply ( readable , eventTarget , returnUint8Arrays ) ;
37+ } else {
38+ return parseLine ( line , readable , returnUint8Arrays ) ;
39+ }
40+ }
2241
2342export async function readReply (
2443 readable : BufferedReadableStream ,
2544 returnUint8Arrays ?: boolean ,
26- ) {
45+ ) : Promise < types . RedisReply > {
2746 const line = await readable . readLine ( ) ;
47+ return parseLine ( line , readable , returnUint8Arrays ) ;
48+ }
49+
50+ async function parseLine (
51+ line : Uint8Array ,
52+ readable : BufferedReadableStream ,
53+ returnUint8Arrays ?: boolean ,
54+ ) : Promise < types . RedisReply > {
2855 const code = line [ 0 ] ;
2956 switch ( code ) {
3057 case ErrorReplyCode : {
@@ -56,16 +83,7 @@ export async function readReply(
5683 }
5784 case ArrayReplyCode :
5885 case PushReplyCode : {
59- const size = Number . parseInt ( decoder . decode ( line . slice ( 1 ) ) ) ;
60- if ( size === - 1 ) {
61- // `-1` indicates a null array
62- return null ;
63- }
64- const array : Array < types . RedisReply > = [ ] ;
65- for ( let i = 0 ; i < size ; i ++ ) {
66- array . push ( await readReply ( readable , returnUint8Arrays ) ) ;
67- }
68- return array ;
86+ return parseArrayLikeReply ( line , readable , returnUint8Arrays ) ;
6987 }
7088 case MapReplyCode : {
7189 // NOTE: We treat a map type as an array to keep backward compatibility.
@@ -130,3 +148,20 @@ export async function readReply(
130148 ) ;
131149 }
132150}
151+
152+ async function parseArrayLikeReply (
153+ line : Uint8Array ,
154+ readable : BufferedReadableStream ,
155+ returnUint8Arrays ?: boolean ,
156+ ) : Promise < Array < types . RedisReply > | null > {
157+ const size = Number . parseInt ( decoder . decode ( line . slice ( 1 ) ) ) ;
158+ if ( size === - 1 ) {
159+ // `-1` indicates a null array
160+ return null ;
161+ }
162+ const array : Array < types . RedisReply > = [ ] ;
163+ for ( let i = 0 ; i < size ; i ++ ) {
164+ array . push ( await readReply ( readable , returnUint8Arrays ) ) ;
165+ }
166+ return array ;
167+ }
0 commit comments