Skip to content

Commit 23b99f8

Browse files
authored
Merge pull request #3 from iuioiua/web-streams
feat: web streams
2 parents 5bffa91 + 0961fd9 commit 23b99f8

File tree

5 files changed

+30
-26
lines changed

5 files changed

+30
-26
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
[![JSR](https://jsr.io/badges/@iuioiua/redis)](https://jsr.io/@iuioiua/redis)
44
[![CI](https://github.com/iuioiua/redis/actions/workflows/ci.yml/badge.svg)](https://github.com/iuioiua/redis/actions/workflows/ci.yml)
55

6-
Minimal [Redis](https://redis.io/) client for [Deno](https://deno.land/).
6+
Lightning-fast, lightweight and reliable [Redis](https://redis.io/) client for
7+
Bun, Cloudflare Workers, Deno and web browsers.
78

89
```ts
910
import { RedisClient } from "@iuioiua/redis";

bench.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/// <reference lib="deno.ns" />
12
import * as denoRedis from "jsr:@db/redis";
23
import { Redis } from "npm:ioredis";
34
import { createClient } from "npm:redis";

deno.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"@std/assert": "jsr:@std/assert@^1.0.11",
77
"@std/bytes": "jsr:@std/bytes@^1.0.5",
88
"@std/collections": "jsr:@std/collections@^1.0.10",
9-
"@std/io": "jsr:@std/io@^0.225.2"
9+
"@std/streams": "jsr:@std/streams@^1.0.9"
1010
},
1111
"tasks": {
1212
"redis:start": "redis-server --save \"\" --appendonly no --daemonize yes",
@@ -19,5 +19,8 @@
1919
},
2020
"exclude": [
2121
"/coverage"
22-
]
22+
],
23+
"compilerOptions": {
24+
"lib": ["dom", "dom.iterable", "dom.asynciterable", "esnext"]
25+
}
2326
}

mod.ts

+20-22
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// deno-lint-ignore-file no-explicit-any
22
import { chunk } from "@std/collections/chunk";
33
import { concat } from "@std/bytes/concat";
4-
import { writeAll } from "@std/io/write-all";
5-
import type { Reader, Writer } from "@std/io/types";
64

75
/**
86
* A Redis client for interacting with a Redis server.
@@ -85,13 +83,12 @@ function createRequest(command: Command): Uint8Array {
8583
return concat(lines);
8684
}
8785

88-
async function* readLines(reader: Reader): AsyncIterableIterator<Uint8Array> {
89-
const buffer = new Uint8Array(1024);
90-
let chunks = new Uint8Array();
91-
while (true) {
92-
const result = await reader.read(buffer);
93-
if (result === null) break;
94-
chunks = concat([chunks, buffer.subarray(0, result)]);
86+
async function* readLines(
87+
readable: ReadableStream<Uint8Array<ArrayBufferLike>>,
88+
) {
89+
let chunks: Uint8Array<ArrayBufferLike> = new Uint8Array(new ArrayBuffer(0));
90+
for await (const chunk of readable) {
91+
chunks = concat([chunks, chunk]) as Uint8Array<ArrayBufferLike>;
9592
let index;
9693
while (
9794
(index = chunks.indexOf(CRLF_BYTES[0])) !== -1 &&
@@ -101,7 +98,6 @@ async function* readLines(reader: Reader): AsyncIterableIterator<Uint8Array> {
10198
chunks = chunks.subarray(index + 2);
10299
}
103100
}
104-
yield chunks;
105101
}
106102

107103
function readNReplies(
@@ -121,9 +117,6 @@ async function readReply(
121117
raw = false,
122118
): Promise<Reply> {
123119
const { value } = await iterator.next();
124-
if (value.length === 0) {
125-
return Promise.reject(new TypeError("No reply received"));
126-
}
127120
switch (value[0]) {
128121
case ARRAY_PREFIX:
129122
case PUSH_PREFIX: {
@@ -376,13 +369,18 @@ async function readReply(
376369
* ```
377370
*/
378371
export class RedisClient {
379-
#conn: Reader & Writer;
372+
#writer: WritableStreamDefaultWriter<Uint8Array>;
380373
#lines: AsyncIterableIterator<Uint8Array>;
381374
#queue: Promise<any> = Promise.resolve();
382375

383-
constructor(conn: Reader & Writer) {
384-
this.#conn = conn;
385-
this.#lines = readLines(this.#conn);
376+
constructor(
377+
conn: {
378+
readable: ReadableStream<Uint8Array>;
379+
writable: WritableStream<Uint8Array>;
380+
},
381+
) {
382+
this.#writer = conn.writable.getWriter();
383+
this.#lines = readLines(conn.readable);
386384
}
387385

388386
#enqueue<T>(task: () => Promise<T>): Promise<T> {
@@ -410,8 +408,8 @@ export class RedisClient {
410408
* ```
411409
*/
412410
sendCommand(command: Command, raw = false): Promise<Reply> {
413-
return this.#enqueue(async () => {
414-
await writeAll(this.#conn, createRequest(command));
411+
return this.#enqueue(() => {
412+
this.#writer.write(createRequest(command));
415413
return readReply(this.#lines, raw);
416414
});
417415
}
@@ -436,7 +434,7 @@ export class RedisClient {
436434
* ```
437435
*/
438436
writeCommand(command: Command): Promise<void> {
439-
return this.#enqueue(() => writeAll(this.#conn, createRequest(command)));
437+
return this.#enqueue(() => this.#writer.write(createRequest(command)));
440438
}
441439

442440
/**
@@ -494,9 +492,9 @@ export class RedisClient {
494492
* ```
495493
*/
496494
pipelineCommands(commands: Command[], raw = false): Promise<Reply[]> {
497-
return this.#enqueue(async () => {
495+
return this.#enqueue(() => {
498496
const bytes = concat(commands.map(createRequest));
499-
await writeAll(this.#conn, bytes);
497+
this.#writer.write(bytes);
500498
return readNReplies(this.#lines, commands.length, raw);
501499
});
502500
}

test.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
/// <reference lib="deno.ns" />
12
import { assertEquals, assertRejects } from "@std/assert";
2-
import { Buffer } from "@std/io/buffer";
3+
import { Buffer } from "@std/streams/buffer";
34
import { type Command, RedisClient, type Reply } from "./mod.ts";
45

56
const redisConn = await Deno.connect({ port: 6379 });

0 commit comments

Comments
 (0)