spindb 0.58.5 → 0.59.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.
- package/dist/cli/commands/restore.js +99 -3
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/config/version.js +1 -1
- package/dist/core/credential-manager.js +7 -0
- package/dist/core/credential-manager.js.map +1 -1
- package/dist/engines/mongo-uri.js +26 -1
- package/dist/engines/mongo-uri.js.map +1 -1
- package/dist/engines/mongodb/backup.js +101 -78
- package/dist/engines/mongodb/backup.js.map +1 -1
- package/dist/engines/mongodb/index.js +6 -6
- package/dist/engines/mongodb/index.js.map +1 -1
- package/dist/engines/mongodb/restore.js +75 -40
- package/dist/engines/mongodb/restore.js.map +1 -1
- package/dist/engines/redis/index.js +1 -1
- package/dist/engines/redis/index.js.map +1 -1
- package/dist/engines/redis/resp-client.js +275 -0
- package/dist/engines/redis/resp-client.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
// Minimal, dependency-free RESP2 client for the one job spindb's external CLI
|
|
2
|
+
// tools cannot do: a binary-safe `SCAN` + `DUMP`/`PTTL` -> `RESTORE` copy
|
|
3
|
+
// between a remote Redis/Valkey (including Upstash over `rediss://`) and a
|
|
4
|
+
// target. `redis-cli` mangles binary `DUMP` payloads in text mode, and the
|
|
5
|
+
// `--rdb`/`BGSAVE` full-snapshot shortcut is blocked on Upstash and most
|
|
6
|
+
// managed Redis - so for the migration path we speak RESP directly over a
|
|
7
|
+
// socket. Scope is deliberately tiny: AUTH, SELECT, PING, DBSIZE, SCAN, DUMP,
|
|
8
|
+
// PTTL, RESTORE, plus pipelining. Keys and payloads are Buffers end to end, so
|
|
9
|
+
// binary values and binary keys round-trip exactly.
|
|
10
|
+
import { connect as netConnect } from 'node:net';
|
|
11
|
+
import { connect as tlsConnect } from 'node:tls';
|
|
12
|
+
const CR = 0x0d;
|
|
13
|
+
const LF = 0x0a;
|
|
14
|
+
// Encode a command as a RESP array of bulk strings. Each argument may be a
|
|
15
|
+
// string (UTF-8) or a Buffer (raw bytes - used for binary keys + DUMP payloads).
|
|
16
|
+
function encodeCommand(args) {
|
|
17
|
+
const parts = [Buffer.from(`*${args.length}\r\n`)];
|
|
18
|
+
for (const arg of args) {
|
|
19
|
+
const buf = Buffer.isBuffer(arg) ? arg : Buffer.from(arg);
|
|
20
|
+
parts.push(Buffer.from(`$${buf.length}\r\n`), buf, Buffer.from('\r\n'));
|
|
21
|
+
}
|
|
22
|
+
return Buffer.concat(parts);
|
|
23
|
+
}
|
|
24
|
+
// Find the index just past the next CRLF at or after `from`, or -1 if the
|
|
25
|
+
// buffer does not yet contain a complete line.
|
|
26
|
+
function indexAfterCrlf(buf, from) {
|
|
27
|
+
for (let i = from; i + 1 < buf.length; i++) {
|
|
28
|
+
if (buf[i] === CR && buf[i + 1] === LF)
|
|
29
|
+
return i + 2;
|
|
30
|
+
}
|
|
31
|
+
return -1;
|
|
32
|
+
}
|
|
33
|
+
// Parse one RESP reply starting at `offset`. Returns the value + the offset
|
|
34
|
+
// just past it, or null when the buffer does not yet hold a complete reply
|
|
35
|
+
// (the caller waits for more bytes and retries). Binary-safe: bulk strings are
|
|
36
|
+
// sliced by their length prefix, never by scanning for delimiters.
|
|
37
|
+
function parseReply(buf, offset) {
|
|
38
|
+
if (offset >= buf.length)
|
|
39
|
+
return null;
|
|
40
|
+
const type = buf[offset];
|
|
41
|
+
const lineEnd = indexAfterCrlf(buf, offset + 1);
|
|
42
|
+
if (lineEnd === -1)
|
|
43
|
+
return null;
|
|
44
|
+
const line = buf.toString('latin1', offset + 1, lineEnd - 2);
|
|
45
|
+
switch (type) {
|
|
46
|
+
case 0x2b: // '+' simple string
|
|
47
|
+
return { value: line, offset: lineEnd };
|
|
48
|
+
case 0x2d: // '-' error
|
|
49
|
+
return { value: new Error(line), offset: lineEnd };
|
|
50
|
+
case 0x3a: // ':' integer
|
|
51
|
+
return { value: Number(line), offset: lineEnd };
|
|
52
|
+
case 0x24: {
|
|
53
|
+
// '$' bulk string
|
|
54
|
+
const len = Number(line);
|
|
55
|
+
if (len === -1)
|
|
56
|
+
return { value: null, offset: lineEnd };
|
|
57
|
+
const end = lineEnd + len;
|
|
58
|
+
if (end + 2 > buf.length)
|
|
59
|
+
return null; // value + trailing CRLF not in yet
|
|
60
|
+
return { value: buf.subarray(lineEnd, end), offset: end + 2 };
|
|
61
|
+
}
|
|
62
|
+
case 0x2a: {
|
|
63
|
+
// '*' array
|
|
64
|
+
const count = Number(line);
|
|
65
|
+
if (count === -1)
|
|
66
|
+
return { value: null, offset: lineEnd };
|
|
67
|
+
const items = [];
|
|
68
|
+
let cur = lineEnd;
|
|
69
|
+
for (let i = 0; i < count; i++) {
|
|
70
|
+
const parsed = parseReply(buf, cur);
|
|
71
|
+
if (!parsed)
|
|
72
|
+
return null;
|
|
73
|
+
items.push(parsed.value);
|
|
74
|
+
cur = parsed.offset;
|
|
75
|
+
}
|
|
76
|
+
return { value: items, offset: cur };
|
|
77
|
+
}
|
|
78
|
+
default:
|
|
79
|
+
throw new Error(`Unsupported RESP reply type: ${String.fromCharCode(type)}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export class RespClient {
|
|
83
|
+
socket;
|
|
84
|
+
inbox = Buffer.alloc(0);
|
|
85
|
+
// FIFO of resolvers, one per in-flight command (pipelining-friendly).
|
|
86
|
+
queue = [];
|
|
87
|
+
fatal = null;
|
|
88
|
+
constructor(socket) {
|
|
89
|
+
this.socket = socket;
|
|
90
|
+
socket.on('data', (chunk) => this.onData(chunk));
|
|
91
|
+
socket.on('error', (err) => this.onFatal(err));
|
|
92
|
+
socket.on('close', () => this.onFatal(new Error('Redis connection closed')));
|
|
93
|
+
}
|
|
94
|
+
onData(chunk) {
|
|
95
|
+
this.inbox = this.inbox.length === 0 ? chunk : Buffer.concat([this.inbox, chunk]);
|
|
96
|
+
let offset = 0;
|
|
97
|
+
for (;;) {
|
|
98
|
+
const parsed = parseReply(this.inbox, offset);
|
|
99
|
+
if (!parsed)
|
|
100
|
+
break;
|
|
101
|
+
offset = parsed.offset;
|
|
102
|
+
const waiter = this.queue.shift();
|
|
103
|
+
if (!waiter)
|
|
104
|
+
continue; // unexpected push (e.g. server-side); ignore
|
|
105
|
+
if (parsed.value instanceof Error)
|
|
106
|
+
waiter.reject(parsed.value);
|
|
107
|
+
else
|
|
108
|
+
waiter.resolve(parsed.value);
|
|
109
|
+
}
|
|
110
|
+
this.inbox = offset === 0 ? this.inbox : this.inbox.subarray(offset);
|
|
111
|
+
}
|
|
112
|
+
onFatal(err) {
|
|
113
|
+
if (this.fatal)
|
|
114
|
+
return;
|
|
115
|
+
this.fatal = err;
|
|
116
|
+
for (const waiter of this.queue)
|
|
117
|
+
waiter.reject(err);
|
|
118
|
+
this.queue = [];
|
|
119
|
+
}
|
|
120
|
+
// Send one command and await its reply.
|
|
121
|
+
command(args) {
|
|
122
|
+
if (this.fatal)
|
|
123
|
+
return Promise.reject(this.fatal);
|
|
124
|
+
const promise = new Promise((resolve, reject) => {
|
|
125
|
+
this.queue.push({ resolve, reject });
|
|
126
|
+
});
|
|
127
|
+
this.socket.write(encodeCommand(args));
|
|
128
|
+
return promise;
|
|
129
|
+
}
|
|
130
|
+
// Send a batch of commands in one write and await all replies in order. This
|
|
131
|
+
// is the throughput lever: dump N keys (DUMP+PTTL) or restore N keys per
|
|
132
|
+
// round-trip instead of one command at a time.
|
|
133
|
+
pipeline(commands) {
|
|
134
|
+
if (this.fatal)
|
|
135
|
+
return Promise.reject(this.fatal);
|
|
136
|
+
const promises = commands.map(() => new Promise((resolve, reject) => {
|
|
137
|
+
this.queue.push({ resolve, reject });
|
|
138
|
+
}));
|
|
139
|
+
this.socket.write(Buffer.concat(commands.map(encodeCommand)));
|
|
140
|
+
return Promise.all(promises);
|
|
141
|
+
}
|
|
142
|
+
close() {
|
|
143
|
+
this.socket.destroy();
|
|
144
|
+
}
|
|
145
|
+
static async connect(opts) {
|
|
146
|
+
const socket = await new Promise((resolve, reject) => {
|
|
147
|
+
const onError = (err) => reject(err);
|
|
148
|
+
const timeoutMs = opts.connectTimeoutMs ?? 15000;
|
|
149
|
+
const s = opts.tls
|
|
150
|
+
? tlsConnect({
|
|
151
|
+
host: opts.host,
|
|
152
|
+
port: opts.port,
|
|
153
|
+
servername: opts.host,
|
|
154
|
+
rejectUnauthorized: opts.rejectUnauthorized ?? false,
|
|
155
|
+
})
|
|
156
|
+
: netConnect({ host: opts.host, port: opts.port });
|
|
157
|
+
const onReady = () => {
|
|
158
|
+
s.removeListener('error', onError);
|
|
159
|
+
s.setTimeout(0);
|
|
160
|
+
resolve(s);
|
|
161
|
+
};
|
|
162
|
+
s.setTimeout(timeoutMs, () => {
|
|
163
|
+
s.destroy();
|
|
164
|
+
reject(new Error(`Redis connection timed out after ${timeoutMs}ms`));
|
|
165
|
+
});
|
|
166
|
+
s.once('error', onError);
|
|
167
|
+
s.once(opts.tls ? 'secureConnect' : 'connect', onReady);
|
|
168
|
+
});
|
|
169
|
+
const client = new RespClient(socket);
|
|
170
|
+
if (opts.password) {
|
|
171
|
+
const authArgs = opts.username && opts.username !== 'default'
|
|
172
|
+
? ['AUTH', opts.username, opts.password]
|
|
173
|
+
: ['AUTH', opts.password];
|
|
174
|
+
await client.command(authArgs);
|
|
175
|
+
}
|
|
176
|
+
if (opts.database && opts.database > 0) {
|
|
177
|
+
await client.command(['SELECT', String(opts.database)]);
|
|
178
|
+
}
|
|
179
|
+
return client;
|
|
180
|
+
}
|
|
181
|
+
// ─── Typed helpers for the migration ops ──────────────────────────
|
|
182
|
+
async ping() {
|
|
183
|
+
await this.command(['PING']);
|
|
184
|
+
}
|
|
185
|
+
async dbsize() {
|
|
186
|
+
const reply = await this.command(['DBSIZE']);
|
|
187
|
+
return typeof reply === 'number' ? reply : 0;
|
|
188
|
+
}
|
|
189
|
+
// One SCAN step. Returns the next cursor ('0' when complete) and the batch of
|
|
190
|
+
// keys as Buffers (binary-safe).
|
|
191
|
+
async scan(cursor, count) {
|
|
192
|
+
const reply = await this.command(['SCAN', cursor, 'COUNT', String(count)]);
|
|
193
|
+
if (!Array.isArray(reply) || reply.length < 2) {
|
|
194
|
+
throw new Error('Unexpected SCAN reply');
|
|
195
|
+
}
|
|
196
|
+
const nextCursor = Buffer.isBuffer(reply[0])
|
|
197
|
+
? reply[0].toString('latin1')
|
|
198
|
+
: String(reply[0]);
|
|
199
|
+
const keysField = reply[1];
|
|
200
|
+
const keys = Array.isArray(keysField)
|
|
201
|
+
? keysField.filter((k) => Buffer.isBuffer(k))
|
|
202
|
+
: [];
|
|
203
|
+
return { cursor: nextCursor, keys };
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Binary-safe keyspace copy: SCAN the source, pipeline DUMP+PTTL per batch, and
|
|
207
|
+
// RESTORE (with TTL, REPLACE) into the target. Preserves every type and TTL
|
|
208
|
+
// exactly because DUMP/RESTORE moves Redis's own serialization. Used by the
|
|
209
|
+
// `restore --from-url` path for redis/valkey. Returns the number of keys copied.
|
|
210
|
+
export async function copyRedisKeyspace(source, target, options = {}) {
|
|
211
|
+
const batchSize = options.batchSize ?? 200;
|
|
212
|
+
const src = await RespClient.connect(source);
|
|
213
|
+
let dst = null;
|
|
214
|
+
try {
|
|
215
|
+
await src.ping();
|
|
216
|
+
const total = await src.dbsize();
|
|
217
|
+
dst = await RespClient.connect(target);
|
|
218
|
+
await dst.ping();
|
|
219
|
+
let cursor = '0';
|
|
220
|
+
let scanned = 0;
|
|
221
|
+
let restored = 0;
|
|
222
|
+
do {
|
|
223
|
+
const { cursor: next, keys } = await src.scan(cursor, batchSize);
|
|
224
|
+
cursor = next;
|
|
225
|
+
if (keys.length === 0)
|
|
226
|
+
continue;
|
|
227
|
+
// DUMP + PTTL for every key in the batch, in one round-trip.
|
|
228
|
+
const probe = await src.pipeline(keys.flatMap((k) => [
|
|
229
|
+
['DUMP', k],
|
|
230
|
+
['PTTL', k],
|
|
231
|
+
]));
|
|
232
|
+
const restoreCmds = [];
|
|
233
|
+
for (let i = 0; i < keys.length; i++) {
|
|
234
|
+
const payload = probe[i * 2];
|
|
235
|
+
const pttl = probe[i * 2 + 1];
|
|
236
|
+
// A key can vanish between SCAN and DUMP; DUMP returns null - skip it.
|
|
237
|
+
if (!Buffer.isBuffer(payload))
|
|
238
|
+
continue;
|
|
239
|
+
const ttlMs = typeof pttl === 'number' && pttl > 0 ? pttl : 0;
|
|
240
|
+
restoreCmds.push([
|
|
241
|
+
'RESTORE',
|
|
242
|
+
keys[i],
|
|
243
|
+
String(ttlMs),
|
|
244
|
+
payload,
|
|
245
|
+
'REPLACE',
|
|
246
|
+
]);
|
|
247
|
+
}
|
|
248
|
+
scanned += keys.length;
|
|
249
|
+
if (restoreCmds.length > 0) {
|
|
250
|
+
try {
|
|
251
|
+
await dst.pipeline(restoreCmds);
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
const message = error.message;
|
|
255
|
+
// RESTORE rejects a DUMP payload whose RDB version is newer than the
|
|
256
|
+
// target supports - i.e. the source is a newer engine version than
|
|
257
|
+
// the target. Surface that plainly instead of the raw checksum error.
|
|
258
|
+
if (/DUMP payload version|checksum are wrong/i.test(message)) {
|
|
259
|
+
throw new Error(`The target is an older engine version than the source, so its binary format is incompatible (${message}). Provision the target at the same major version as the source, or newer, and retry.`);
|
|
260
|
+
}
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
restored += restoreCmds.length;
|
|
264
|
+
}
|
|
265
|
+
options.onProgress?.({ scanned, restored, total });
|
|
266
|
+
} while (cursor !== '0');
|
|
267
|
+
return { keysCopied: restored, total };
|
|
268
|
+
}
|
|
269
|
+
finally {
|
|
270
|
+
src.close();
|
|
271
|
+
if (dst)
|
|
272
|
+
dst.close();
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=resp-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resp-client.js","sourceRoot":"","sources":["../../../engines/redis/resp-client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spindb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.59.0",
|
|
4
4
|
"author": "Bob Bass <bob@bbass.co>",
|
|
5
5
|
"license": "PolyForm-Noncommercial-1.0.0",
|
|
6
6
|
"description": "Zero-config Docker-free local database containers. Create, backup, and clone a variety of popular databases.",
|