@crvouga/mockingbird-service-redis 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,266 @@
1
+ interface RedisClock {
2
+ now(): number;
3
+ advance(ms: number): void;
4
+ subscribe(listener: () => void): () => void;
5
+ readonly manual: boolean;
6
+ }
7
+
8
+ type Reply = {
9
+ t: "simple";
10
+ v: string;
11
+ } | {
12
+ t: "error";
13
+ v: string;
14
+ } | {
15
+ t: "int";
16
+ v: number | bigint;
17
+ } | {
18
+ t: "bulk";
19
+ v: Uint8Array | null;
20
+ } | {
21
+ t: "array";
22
+ v: Reply[] | null;
23
+ } | {
24
+ t: "null";
25
+ } | {
26
+ t: "bool";
27
+ v: boolean;
28
+ } | {
29
+ t: "double";
30
+ v: number;
31
+ } | {
32
+ t: "map";
33
+ v: Array<[Reply, Reply]>;
34
+ } | {
35
+ t: "push";
36
+ v: Reply[];
37
+ };
38
+
39
+ interface RedisUser {
40
+ name: string;
41
+ password: string;
42
+ readOnly?: boolean;
43
+ }
44
+ interface RedisOptions {
45
+ clock?: RedisClock;
46
+ databases?: number;
47
+ password?: string;
48
+ users?: RedisUser[];
49
+ maxmemory?: number;
50
+ maxmemoryPolicy?: "noeviction" | "allkeys-lru";
51
+ seed?: number;
52
+ }
53
+ type RedisFault = "readonly" | "oom" | "busy" | "disconnect" | "timeout" | {
54
+ latencyMs: number;
55
+ } | null;
56
+ interface Session {
57
+ id: number;
58
+ db: number;
59
+ protocol: 2 | 3;
60
+ name: string;
61
+ libName: string;
62
+ libVer: string;
63
+ authenticated: boolean;
64
+ username: string;
65
+ readOnly: boolean;
66
+ multi: Array<{
67
+ name: string;
68
+ args: Uint8Array[];
69
+ }> | null;
70
+ multiFailed: boolean;
71
+ watching: Array<{
72
+ db: number;
73
+ key: string;
74
+ gen: number;
75
+ }>;
76
+ channels: Set<string>;
77
+ patterns: Set<string>;
78
+ dead: boolean;
79
+ quit: boolean;
80
+ inExec: boolean;
81
+ onPush: (reply: Reply) => void;
82
+ }
83
+ declare class Redis {
84
+ readonly clock: RedisClock;
85
+ private readonly dbs;
86
+ private readonly password;
87
+ private readonly users;
88
+ private readonly authRequired;
89
+ readonly maxmemory: number;
90
+ private policy;
91
+ private rngState;
92
+ private faultValue;
93
+ private tail;
94
+ private sessions;
95
+ private nextClientId;
96
+ private waiters;
97
+ private channelSubs;
98
+ private patternSubs;
99
+ private scripts;
100
+ private invoked;
101
+ private scriptDepth;
102
+ private commandCount;
103
+ private closed;
104
+ consumersPaused: boolean;
105
+ private readonly disconnectListeners;
106
+ constructor(options?: RedisOptions);
107
+ client(): RedisClient;
108
+ advance(ms: number): void;
109
+ fault(value: RedisFault): void;
110
+ pauseConsumers(paused?: boolean): void;
111
+ waiterCount(): number;
112
+ inspect(db?: number): Array<{
113
+ key: string;
114
+ type: string;
115
+ pttl: number;
116
+ }>;
117
+ reset(): void;
118
+ close(): void;
119
+ onDisconnect(listener: (session: Session) => void): () => void;
120
+ createSession(): Session;
121
+ perform(session: Session, name: string, args: Uint8Array[]): Promise<Reply>;
122
+ private enqueue;
123
+ private applyLatency;
124
+ private dropSession;
125
+ private sessionOf;
126
+ private database;
127
+ private random;
128
+ private memory;
129
+ private dispatch;
130
+ private execCmd;
131
+ private guardWrite;
132
+ private cmdPing;
133
+ private cmdAuth;
134
+ private cmdHello;
135
+ private cmdSelect;
136
+ private cmdReset;
137
+ private cmdClient;
138
+ private clientInfo;
139
+ private info;
140
+ private keyspaceLines;
141
+ private cmdTime;
142
+ private cmdConfig;
143
+ private cmdRandomKey;
144
+ private cmdScan;
145
+ private cmdKeys;
146
+ private cmdType;
147
+ private cmdExists;
148
+ private cmdDel;
149
+ private cmdRename;
150
+ private cmdExpire;
151
+ private cmdTtl;
152
+ private cmdPersist;
153
+ private stringAt;
154
+ private cmdGet;
155
+ private cmdSet;
156
+ private cmdMget;
157
+ private cmdMset;
158
+ private cmdAppend;
159
+ private cmdStrlen;
160
+ private cmdGetRange;
161
+ private cmdSetRange;
162
+ private cmdIncr;
163
+ private cmdIncrBy;
164
+ private addInteger;
165
+ private cmdIncrByFloat;
166
+ private cmdGetDel;
167
+ private cmdGetEx;
168
+ private requireHash;
169
+ private cmdHash;
170
+ private requireList;
171
+ private cmdList;
172
+ private cmdBlockingList;
173
+ private takeList;
174
+ private requireSet;
175
+ private cmdSetFamily;
176
+ private requireZset;
177
+ private cmdZset;
178
+ private cmdZadd;
179
+ private cmdZrange;
180
+ private cmdBlockingZset;
181
+ private takeZset;
182
+ private cmdStream;
183
+ private stream;
184
+ private cmdXadd;
185
+ private nextId;
186
+ private cmdXrange;
187
+ private cmdXdel;
188
+ private cmdXtrim;
189
+ private cmdXgroup;
190
+ private cmdXread;
191
+ private readStreams;
192
+ private cmdXack;
193
+ private cmdXpending;
194
+ private cmdXclaim;
195
+ private cmdXinfo;
196
+ private cmdSub;
197
+ private cmdPublish;
198
+ private cmdPubsub;
199
+ private cmdExec;
200
+ private cmdDiscard;
201
+ private cmdWatch;
202
+ private cmdEval;
203
+ private cmdScript;
204
+ private runScript;
205
+ private luaDispatch;
206
+ private block;
207
+ private wake;
208
+ private wakeAll;
209
+ private satisfy;
210
+ private finishWaiter;
211
+ private failWaiter;
212
+ private leavePubsub;
213
+ }
214
+ declare class RedisClient {
215
+ private readonly redis;
216
+ private readonly session;
217
+ constructor(redis: Redis, session: Session);
218
+ get protocol(): 2 | 3;
219
+ onPush(listener: (reply: Reply) => void): void;
220
+ call(command: string, ...args: Array<string | number | Uint8Array>): Promise<unknown>;
221
+ raw(command: string, ...args: Array<string | number | Uint8Array>): Promise<Reply>;
222
+ pipeline(): RedisPipeline;
223
+ quit(): Promise<string>;
224
+ }
225
+ declare class RedisPipeline {
226
+ private readonly client;
227
+ private readonly commands;
228
+ constructor(client: RedisClient);
229
+ call(name: string, ...args: Array<string | number | Uint8Array>): this;
230
+ exec(): Promise<unknown[]>;
231
+ }
232
+
233
+ /** HTTP port for `serve --config`. The RESP socket binds an ephemeral port. */
234
+ declare const DEFAULT_PORT = 8827;
235
+ interface ServeOptions {
236
+ port?: number;
237
+ host?: string;
238
+ }
239
+ interface RedisListening {
240
+ host: string;
241
+ port: number;
242
+ close(): Promise<void>;
243
+ }
244
+ declare function serve(redis: Redis, options?: ServeOptions): Promise<RedisListening>;
245
+ type FleetRuntime = {
246
+ fetch(request: Request): Promise<Response>;
247
+ respPort: number;
248
+ close(): Promise<void>;
249
+ };
250
+ type HttpListening = {
251
+ close(): Promise<void>;
252
+ };
253
+ /**
254
+ * Fleet entry for `serve --config`. HTTP `GET /health` reports `service: redis`.
255
+ * RESP listens on an ephemeral port named in the startup banner.
256
+ */
257
+ declare const serveTarget: {
258
+ name: string;
259
+ defaultPort: number;
260
+ create(): Promise<FleetRuntime>;
261
+ listening(http: HttpListening): void;
262
+ banner(runtime: FleetRuntime): string[];
263
+ };
264
+
265
+ export { DEFAULT_PORT, serve, serveTarget };
266
+ export type { RedisListening, ServeOptions };
package/dist/server.js ADDED
@@ -0,0 +1,12 @@
1
+ import {
2
+ DEFAULT_PORT,
3
+ serve,
4
+ serveTarget
5
+ } from "./chunk-7U5RQF7K.js";
6
+ import "./chunk-4HDEOTYJ.js";
7
+ export {
8
+ DEFAULT_PORT,
9
+ serve,
10
+ serveTarget
11
+ };
12
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@crvouga/mockingbird-service-redis",
3
+ "version": "0.1.0",
4
+ "description": "In-process Redis RESP server for tests: strings, hashes, lists, sets, sorted sets, streams, transactions, pub/sub, and a Lua subset, with an injected clock. Not an HTTP mock.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "SUPPORT.md"
12
+ ],
13
+ "main": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "default": "./dist/index.js"
19
+ },
20
+ "./server": {
21
+ "types": "./dist/server.d.ts",
22
+ "default": "./dist/server.js"
23
+ }
24
+ },
25
+ "bin": {
26
+ "mockingbird-redis": "./dist/cli.js"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public",
30
+ "provenance": true
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/crvouga/mockingbird.git",
35
+ "directory": "packages/service/redis"
36
+ },
37
+ "homepage": "https://github.com/crvouga/mockingbird/tree/main/packages/service/redis#readme",
38
+ "keywords": [
39
+ "mockingbird",
40
+ "redis",
41
+ "resp",
42
+ "mock"
43
+ ],
44
+ "mockingbird": {
45
+ "runtime": "portable",
46
+ "entries": {
47
+ "server": "node",
48
+ "cli": "node"
49
+ },
50
+ "layer": "service",
51
+ "category": "databases",
52
+ "displayName": "Redis",
53
+ "status": "wip",
54
+ "vendor": {
55
+ "website": "https://redis.io",
56
+ "docs": "https://redis.io/docs/latest/commands/",
57
+ "icon": "redis",
58
+ "color": "#FF4438"
59
+ },
60
+ "parity": "RESP replies, expiration, transactions, and streams",
61
+ "parityTier": "cold"
62
+ },
63
+ "scripts": {
64
+ "build": "bun ../../../scripts/bundle-service.ts",
65
+ "typecheck": "tsc -p tsconfig.json --noEmit",
66
+ "lint": "biome check .",
67
+ "test": "bun test",
68
+ "parity": "bun scripts/parity.ts",
69
+ "portability": "bun ../../../scripts/portability.ts",
70
+ "pack:check": "bun ../../../scripts/pack-check.ts"
71
+ },
72
+ "devDependencies": {
73
+ "@crvouga/mockingbird-credentials": "0.0.0-development",
74
+ "ioredis": "5.11.1"
75
+ }
76
+ }