@arcaelas/whatsapp 4.5.0 → 5.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.
- package/build/cjs/index.d.ts +6 -4
- package/build/cjs/index.js +22 -2
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/lib/bot/decorator.d.ts +2 -0
- package/build/cjs/lib/bot/decorator.js +6 -0
- package/build/cjs/lib/bot/decorator.js.map +1 -1
- package/build/cjs/lib/chat/index.d.ts +340 -204
- package/build/cjs/lib/chat/index.js +225 -213
- package/build/cjs/lib/chat/index.js.map +1 -1
- package/build/cjs/lib/contact/index.d.ts +162 -179
- package/build/cjs/lib/contact/index.js +96 -190
- package/build/cjs/lib/contact/index.js.map +1 -1
- package/build/cjs/lib/internal.d.ts +40 -0
- package/build/cjs/lib/internal.js +39 -0
- package/build/cjs/lib/internal.js.map +1 -0
- package/build/cjs/lib/message/index.d.ts +462 -289
- package/build/cjs/lib/message/index.js +825 -741
- package/build/cjs/lib/message/index.js.map +1 -1
- package/build/cjs/lib/status/index.d.ts +60 -70
- package/build/cjs/lib/status/index.js +106 -111
- package/build/cjs/lib/status/index.js.map +1 -1
- package/build/cjs/lib/store/engine/index.d.ts +21 -7
- package/build/cjs/lib/store/engine/index.js +6 -3
- package/build/cjs/lib/store/engine/index.js.map +1 -1
- package/build/cjs/lib/store/engine/lib/file_system/index.d.ts +38 -8
- package/build/cjs/lib/store/engine/lib/file_system/index.js +92 -67
- package/build/cjs/lib/store/engine/lib/file_system/index.js.map +1 -1
- package/build/cjs/lib/store/engine/lib/index.d.ts +112 -0
- package/build/cjs/lib/store/engine/lib/index.js +213 -0
- package/build/cjs/lib/store/engine/lib/index.js.map +1 -0
- package/build/cjs/lib/store/engine/lib/redis/index.d.ts +28 -13
- package/build/cjs/lib/store/engine/lib/redis/index.js +56 -42
- package/build/cjs/lib/store/engine/lib/redis/index.js.map +1 -1
- package/build/cjs/lib/store/engine/lib/s3/index.d.ts +44 -1
- package/build/cjs/lib/store/engine/lib/s3/index.js +112 -64
- package/build/cjs/lib/store/engine/lib/s3/index.js.map +1 -1
- package/build/cjs/lib/store/engine/lib/sqlite/index.d.ts +98 -0
- package/build/cjs/lib/store/engine/lib/sqlite/index.js +114 -0
- package/build/cjs/lib/store/engine/lib/sqlite/index.js.map +1 -0
- package/build/cjs/lib/store/index.d.ts +7 -3
- package/build/cjs/lib/store/index.js +14 -4
- package/build/cjs/lib/store/index.js.map +1 -1
- package/build/cjs/lib/whatsapp/index.d.ts +106 -68
- package/build/cjs/lib/whatsapp/index.js +380 -170
- package/build/cjs/lib/whatsapp/index.js.map +1 -1
- package/build/cjs/test.js +5 -4
- package/build/cjs/test.js.map +1 -1
- package/build/esm/index.d.ts +6 -4
- package/build/esm/index.js +5 -2
- package/build/esm/index.js.map +1 -1
- package/build/esm/lib/bot/decorator.d.ts +2 -0
- package/build/esm/lib/bot/decorator.js +6 -0
- package/build/esm/lib/bot/decorator.js.map +1 -1
- package/build/esm/lib/chat/index.d.ts +340 -204
- package/build/esm/lib/chat/index.js +225 -213
- package/build/esm/lib/chat/index.js.map +1 -1
- package/build/esm/lib/contact/index.d.ts +162 -179
- package/build/esm/lib/contact/index.js +96 -189
- package/build/esm/lib/contact/index.js.map +1 -1
- package/build/esm/lib/internal.d.ts +40 -0
- package/build/esm/lib/internal.js +35 -0
- package/build/esm/lib/internal.js.map +1 -0
- package/build/esm/lib/message/index.d.ts +462 -289
- package/build/esm/lib/message/index.js +820 -736
- package/build/esm/lib/message/index.js.map +1 -1
- package/build/esm/lib/status/index.d.ts +60 -70
- package/build/esm/lib/status/index.js +105 -110
- package/build/esm/lib/status/index.js.map +1 -1
- package/build/esm/lib/store/engine/index.d.ts +21 -7
- package/build/esm/lib/store/engine/index.js +4 -2
- package/build/esm/lib/store/engine/index.js.map +1 -1
- package/build/esm/lib/store/engine/lib/file_system/index.d.ts +38 -8
- package/build/esm/lib/store/engine/lib/file_system/index.js +92 -67
- package/build/esm/lib/store/engine/lib/file_system/index.js.map +1 -1
- package/build/esm/lib/store/engine/lib/index.d.ts +112 -0
- package/build/esm/lib/store/engine/lib/index.js +206 -0
- package/build/esm/lib/store/engine/lib/index.js.map +1 -0
- package/build/esm/lib/store/engine/lib/redis/index.d.ts +28 -13
- package/build/esm/lib/store/engine/lib/redis/index.js +54 -40
- package/build/esm/lib/store/engine/lib/redis/index.js.map +1 -1
- package/build/esm/lib/store/engine/lib/s3/index.d.ts +44 -1
- package/build/esm/lib/store/engine/lib/s3/index.js +111 -63
- package/build/esm/lib/store/engine/lib/s3/index.js.map +1 -1
- package/build/esm/lib/store/engine/lib/sqlite/index.d.ts +98 -0
- package/build/esm/lib/store/engine/lib/sqlite/index.js +110 -0
- package/build/esm/lib/store/engine/lib/sqlite/index.js.map +1 -0
- package/build/esm/lib/store/index.d.ts +7 -3
- package/build/esm/lib/store/index.js +13 -4
- package/build/esm/lib/store/index.js.map +1 -1
- package/build/esm/lib/whatsapp/index.d.ts +106 -68
- package/build/esm/lib/whatsapp/index.js +382 -172
- package/build/esm/lib/whatsapp/index.js.map +1 -1
- package/build/esm/test.js +5 -4
- package/build/esm/test.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file store/engine/lib/index.ts
|
|
4
|
+
* @description Utilidades compartidas por los drivers: índice ordenado por directorio,
|
|
5
|
+
* caché LRU de índices y normalización de rutas.
|
|
6
|
+
* Shared driver utilities: per-directory sorted index, LRU index cache and path normalization.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.IndexCache = exports.SortedIndex = void 0;
|
|
10
|
+
exports.normalize_path = normalize_path;
|
|
11
|
+
exports.split_path = split_path;
|
|
12
|
+
/**
|
|
13
|
+
* @internal
|
|
14
|
+
* Índice ordenado por score DESC de los hijos de un directorio, mantenido incrementalmente:
|
|
15
|
+
* `page()` recorta sin re-ordenar y `set`/`delete` reubican una sola entrada por búsqueda
|
|
16
|
+
* binaria. Persiste su contenido con el callback `_flush`, agrupando ráfagas de escritura.
|
|
17
|
+
*
|
|
18
|
+
* Score-DESC sorted index of a directory's children, kept incrementally: `page()` slices
|
|
19
|
+
* without re-sorting and `set`/`delete` relocate a single entry via binary search. Persists
|
|
20
|
+
* through the `_flush` callback, coalescing write bursts.
|
|
21
|
+
*/
|
|
22
|
+
class SortedIndex {
|
|
23
|
+
/**
|
|
24
|
+
* @param _flush - Persiste el índice; recibe los pares ordenados / Persists the index; receives the ordered pairs
|
|
25
|
+
* @param _delay - Espera antes de persistir, agrupando ráfagas / Wait before persisting, coalescing bursts
|
|
26
|
+
*/
|
|
27
|
+
constructor(_flush, _delay = 1_000) {
|
|
28
|
+
this._flush = _flush;
|
|
29
|
+
this._delay = _delay;
|
|
30
|
+
/** @internal Nombres ordenados por score DESC. / Names ordered by score DESC. */
|
|
31
|
+
this._order = [];
|
|
32
|
+
/** @internal Score vigente de cada nombre. / Current score per name. */
|
|
33
|
+
this._scores = new Map();
|
|
34
|
+
this._dirty = false;
|
|
35
|
+
this._timer = null;
|
|
36
|
+
}
|
|
37
|
+
/** Cantidad de hijos indexados. / Indexed children count. */
|
|
38
|
+
get size() {
|
|
39
|
+
return this._order.length;
|
|
40
|
+
}
|
|
41
|
+
/** Pares `[nombre, score]` en orden DESC. / `[name, score]` pairs in DESC order. */
|
|
42
|
+
get entries() {
|
|
43
|
+
return this._order.map((name) => [name, this._scores.get(name) ?? 0]);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Reemplaza el índice completo con las entradas dadas, ordenándolas una sola vez.
|
|
47
|
+
* Replaces the whole index with the given entries, sorting them once.
|
|
48
|
+
*/
|
|
49
|
+
load(entries) {
|
|
50
|
+
const pairs = [...entries].sort((a, b) => b[1] - a[1]);
|
|
51
|
+
this._order = pairs.map(([name]) => name);
|
|
52
|
+
this._scores = new Map(pairs);
|
|
53
|
+
}
|
|
54
|
+
/** Página de nombres en orden DESC, sin re-ordenar. / Page of names in DESC order, no re-sorting. */
|
|
55
|
+
page(offset, limit) {
|
|
56
|
+
return this._order.slice(offset, offset + limit);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Inserta o reubica un hijo con su score, manteniendo el orden.
|
|
60
|
+
* Inserts or relocates a child with its score, keeping the order.
|
|
61
|
+
*/
|
|
62
|
+
set(name, score) {
|
|
63
|
+
this._detach(name);
|
|
64
|
+
this._order.splice(this._locate(score), 0, name);
|
|
65
|
+
this._scores.set(name, score);
|
|
66
|
+
this._schedule();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Quita un hijo del índice.
|
|
70
|
+
* Removes a child from the index.
|
|
71
|
+
*/
|
|
72
|
+
delete(name) {
|
|
73
|
+
if (this._scores.has(name)) {
|
|
74
|
+
this._detach(name);
|
|
75
|
+
this._schedule();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Cancela la persistencia pendiente; se usa al descartar el índice de la caché.
|
|
80
|
+
* Cancels the pending persistence; used when dropping the index from the cache.
|
|
81
|
+
*/
|
|
82
|
+
dispose() {
|
|
83
|
+
if (this._timer) {
|
|
84
|
+
clearTimeout(this._timer);
|
|
85
|
+
this._timer = null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** @internal Saca el nombre de la lista ordenada si estaba presente. / Detaches the name from the ordered list when present. */
|
|
89
|
+
_detach(name) {
|
|
90
|
+
const previous = this._scores.get(name);
|
|
91
|
+
if (previous !== undefined) {
|
|
92
|
+
let position = this._locate(previous);
|
|
93
|
+
while (position < this._order.length && this._order[position] !== name) {
|
|
94
|
+
position++;
|
|
95
|
+
}
|
|
96
|
+
if (position < this._order.length) {
|
|
97
|
+
this._order.splice(position, 1);
|
|
98
|
+
}
|
|
99
|
+
this._scores.delete(name);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** @internal Primera posición cuyo score es menor o igual al dado (orden DESC). / First position whose score is lower or equal to the given one (DESC order). */
|
|
103
|
+
_locate(score) {
|
|
104
|
+
let low = 0;
|
|
105
|
+
let high = this._order.length;
|
|
106
|
+
while (low < high) {
|
|
107
|
+
const middle = (low + high) >> 1;
|
|
108
|
+
if ((this._scores.get(this._order[middle]) ?? 0) > score) {
|
|
109
|
+
low = middle + 1;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
high = middle;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return low;
|
|
116
|
+
}
|
|
117
|
+
/** @internal Programa la persistencia diferida. / Schedules the deferred persistence. */
|
|
118
|
+
_schedule() {
|
|
119
|
+
this._dirty = true;
|
|
120
|
+
if (!this._timer) {
|
|
121
|
+
this._timer = setTimeout(() => {
|
|
122
|
+
this._timer = null;
|
|
123
|
+
if (this._dirty) {
|
|
124
|
+
this._dirty = false;
|
|
125
|
+
void this._flush(this.entries).catch(() => { });
|
|
126
|
+
}
|
|
127
|
+
}, this._delay);
|
|
128
|
+
this._timer.unref?.();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
exports.SortedIndex = SortedIndex;
|
|
133
|
+
/**
|
|
134
|
+
* @internal
|
|
135
|
+
* Caché LRU de índices por directorio: mantiene acotada la memoria del driver descartando
|
|
136
|
+
* el directorio menos usado cuando se supera el límite.
|
|
137
|
+
* Per-directory LRU cache of indexes: keeps driver memory bounded by dropping the
|
|
138
|
+
* least-recently-used directory once the limit is exceeded.
|
|
139
|
+
*/
|
|
140
|
+
class IndexCache {
|
|
141
|
+
/** @param _limit - Directorios indexados simultáneamente / Simultaneously indexed directories */
|
|
142
|
+
constructor(_limit = 12) {
|
|
143
|
+
this._limit = _limit;
|
|
144
|
+
this._cache = new Map();
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Índice ya cargado del directorio, marcándolo como recién usado.
|
|
148
|
+
* Already loaded index for the directory, marking it as recently used.
|
|
149
|
+
*/
|
|
150
|
+
get(key) {
|
|
151
|
+
const index = this._cache.get(key);
|
|
152
|
+
if (index) {
|
|
153
|
+
this._cache.delete(key);
|
|
154
|
+
this._cache.set(key, index);
|
|
155
|
+
}
|
|
156
|
+
return index;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Registra el índice del directorio, descartando el menos usado si se supera el límite.
|
|
160
|
+
* Registers the directory index, dropping the least used one when over the limit.
|
|
161
|
+
*/
|
|
162
|
+
set(key, index) {
|
|
163
|
+
this._cache.set(key, index);
|
|
164
|
+
while (this._cache.size > this._limit) {
|
|
165
|
+
const oldest = this._cache.keys().next().value;
|
|
166
|
+
this._cache.get(oldest)?.dispose();
|
|
167
|
+
this._cache.delete(oldest);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Descarta el índice del directorio y de todo su sub-árbol.
|
|
172
|
+
* Drops the directory index and its whole subtree.
|
|
173
|
+
*/
|
|
174
|
+
drop(key) {
|
|
175
|
+
for (const cached of [...this._cache.keys()]) {
|
|
176
|
+
if (cached === key || cached.startsWith(`${key}/`)) {
|
|
177
|
+
this._cache.get(cached)?.dispose();
|
|
178
|
+
this._cache.delete(cached);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/** Vacía la caché completa. / Clears the whole cache. */
|
|
183
|
+
clear() {
|
|
184
|
+
for (const index of this._cache.values()) {
|
|
185
|
+
index.dispose();
|
|
186
|
+
}
|
|
187
|
+
this._cache.clear();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
exports.IndexCache = IndexCache;
|
|
191
|
+
/**
|
|
192
|
+
* Normaliza un path colapsando slashes redundantes y recortando los extremos.
|
|
193
|
+
* Normalizes a path collapsing redundant slashes and trimming both ends.
|
|
194
|
+
*
|
|
195
|
+
* @param path - Ruta cruda / Raw path
|
|
196
|
+
* @returns Ruta normalizada / Normalized path
|
|
197
|
+
*/
|
|
198
|
+
function normalize_path(path) {
|
|
199
|
+
return path.replace(/\/+/g, '/').replace(/^\/|\/$/g, '');
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Separa una ruta normalizada en directorio padre y nombre del hijo.
|
|
203
|
+
* Splits a normalized path into parent directory and child name.
|
|
204
|
+
*
|
|
205
|
+
* @param path - Ruta a separar / Path to split
|
|
206
|
+
* @returns `{ parent, name }` / `{ parent, name }`
|
|
207
|
+
*/
|
|
208
|
+
function split_path(path) {
|
|
209
|
+
const full = normalize_path(path);
|
|
210
|
+
const cut = full.lastIndexOf('/');
|
|
211
|
+
return cut === -1 ? { parent: '', name: full } : { parent: full.slice(0, cut), name: full.slice(cut + 1) };
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/lib/store/engine/lib/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { Engine } from '../../../../../lib/store/engine';
|
|
7
7
|
/**
|
|
8
|
-
* Interface mínima del cliente Redis (compatible con ioredis).
|
|
9
|
-
*
|
|
8
|
+
* Interface mínima del cliente Redis (compatible con ioredis). `pipeline` es opcional:
|
|
9
|
+
* cuando existe, las escrituras que tocan documento e índice viajan en un solo round-trip.
|
|
10
|
+
* Minimal Redis client interface (ioredis-compatible). `pipeline` is optional: when present,
|
|
11
|
+
* writes touching document and index travel in a single round-trip.
|
|
10
12
|
*/
|
|
11
13
|
export interface RedisClient {
|
|
12
14
|
get(key: string): Promise<string | null>;
|
|
@@ -18,15 +20,28 @@ export interface RedisClient {
|
|
|
18
20
|
zrem(key: string, members: string | string[]): Promise<unknown>;
|
|
19
21
|
zrevrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
20
22
|
zcard(key: string): Promise<number>;
|
|
23
|
+
pipeline?(): {
|
|
24
|
+
set(key: string, value: string): unknown;
|
|
25
|
+
del(keys: string | string[]): unknown;
|
|
26
|
+
zadd(key: string, score: number, member: string): unknown;
|
|
27
|
+
zrem(key: string, members: string | string[]): unknown;
|
|
28
|
+
exec(): Promise<unknown>;
|
|
29
|
+
};
|
|
21
30
|
}
|
|
22
31
|
/**
|
|
23
32
|
* Driver de persistencia con Redis.
|
|
24
33
|
*
|
|
25
34
|
* Keyspaces:
|
|
26
35
|
* - `<prefix>:doc:<path>` → string del documento.
|
|
27
|
-
* - `<prefix>:idx:<parent>` → sorted set (score
|
|
36
|
+
* - `<prefix>:idx:<parent>` → sorted set (score explícito o de escritura, member=path completo).
|
|
28
37
|
*
|
|
29
|
-
* `list` combina ZREVRANGE + MGET
|
|
38
|
+
* El índice ordenado vive en Redis: `list` combina ZREVRANGE + MGET (dos round-trips, O(log N + M))
|
|
39
|
+
* y `count` es un ZCARD O(1); las escrituras agrupan documento e índice en un pipeline para que
|
|
40
|
+
* no queden documentos huérfanos del índice si el proceso muere entre ambas operaciones.
|
|
41
|
+
*
|
|
42
|
+
* Redis persistence driver. The sorted index lives in Redis: `list` combines ZREVRANGE + MGET
|
|
43
|
+
* and `count` is an O(1) ZCARD; writes group document and index in a pipeline so no document
|
|
44
|
+
* is left orphaned from the index when the process dies between both operations.
|
|
30
45
|
*
|
|
31
46
|
* @example
|
|
32
47
|
* import IORedis from 'ioredis';
|
|
@@ -40,26 +55,26 @@ export declare class RedisEngine implements Engine {
|
|
|
40
55
|
private _doc_key;
|
|
41
56
|
/** @internal */
|
|
42
57
|
private _idx_key;
|
|
43
|
-
/** @internal */
|
|
44
|
-
private _split;
|
|
45
58
|
/**
|
|
46
59
|
* Lee el valor de un documento.
|
|
47
60
|
* Reads a document's value.
|
|
48
61
|
*/
|
|
49
62
|
get(path: string): Promise<string | null>;
|
|
50
63
|
/**
|
|
51
|
-
* Escribe el valor y
|
|
52
|
-
*
|
|
64
|
+
* Escribe el valor y su entrada de índice en una sola operación; `score` fija el orden
|
|
65
|
+
* de `list` (por defecto, la hora de escritura).
|
|
66
|
+
* Writes the value and its index entry in a single operation; `score` drives `list`
|
|
67
|
+
* ordering (write time by default).
|
|
53
68
|
*/
|
|
54
|
-
set(path: string, value: string): Promise<void>;
|
|
69
|
+
set(path: string, value: string, score?: number): Promise<void>;
|
|
55
70
|
/**
|
|
56
|
-
* Elimina el doc, su índice y todo el sub-árbol.
|
|
57
|
-
* Deletes the doc, its index, and the entire subtree.
|
|
71
|
+
* Elimina el doc, su entrada de índice y todo el sub-árbol.
|
|
72
|
+
* Deletes the doc, its index entry, and the entire subtree.
|
|
58
73
|
*/
|
|
59
74
|
unset(path: string): Promise<boolean>;
|
|
60
75
|
/**
|
|
61
|
-
* Lista valores de los hijos directos, ordenados por
|
|
62
|
-
* Lists direct children values ordered by
|
|
76
|
+
* Lista valores de los hijos directos, ordenados por score DESC en dos round-trips.
|
|
77
|
+
* Lists direct children values ordered by score DESC in two round-trips.
|
|
63
78
|
*/
|
|
64
79
|
list(path: string, offset?: number, limit?: number): Promise<string[]>;
|
|
65
80
|
/**
|
|
@@ -6,21 +6,21 @@
|
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.RedisEngine = void 0;
|
|
9
|
-
|
|
10
|
-
* Normaliza un path colapsando slashes redundantes.
|
|
11
|
-
* Normalizes a path by collapsing redundant slashes.
|
|
12
|
-
*/
|
|
13
|
-
function normalize_path(path) {
|
|
14
|
-
return path.replace(/\/+/g, '/').replace(/^\/|\/$/g, '');
|
|
15
|
-
}
|
|
9
|
+
const lib_1 = require("../../../../../lib/store/engine/lib");
|
|
16
10
|
/**
|
|
17
11
|
* Driver de persistencia con Redis.
|
|
18
12
|
*
|
|
19
13
|
* Keyspaces:
|
|
20
14
|
* - `<prefix>:doc:<path>` → string del documento.
|
|
21
|
-
* - `<prefix>:idx:<parent>` → sorted set (score
|
|
15
|
+
* - `<prefix>:idx:<parent>` → sorted set (score explícito o de escritura, member=path completo).
|
|
22
16
|
*
|
|
23
|
-
* `list` combina ZREVRANGE + MGET
|
|
17
|
+
* El índice ordenado vive en Redis: `list` combina ZREVRANGE + MGET (dos round-trips, O(log N + M))
|
|
18
|
+
* y `count` es un ZCARD O(1); las escrituras agrupan documento e índice en un pipeline para que
|
|
19
|
+
* no queden documentos huérfanos del índice si el proceso muere entre ambas operaciones.
|
|
20
|
+
*
|
|
21
|
+
* Redis persistence driver. The sorted index lives in Redis: `list` combines ZREVRANGE + MGET
|
|
22
|
+
* and `count` is an O(1) ZCARD; writes group document and index in a pipeline so no document
|
|
23
|
+
* is left orphaned from the index when the process dies between both operations.
|
|
24
24
|
*
|
|
25
25
|
* @example
|
|
26
26
|
* import IORedis from 'ioredis';
|
|
@@ -33,20 +33,11 @@ class RedisEngine {
|
|
|
33
33
|
}
|
|
34
34
|
/** @internal */
|
|
35
35
|
_doc_key(path) {
|
|
36
|
-
return `${this._prefix}:doc:${normalize_path(path)}`;
|
|
36
|
+
return `${this._prefix}:doc:${(0, lib_1.normalize_path)(path)}`;
|
|
37
37
|
}
|
|
38
38
|
/** @internal */
|
|
39
39
|
_idx_key(parent) {
|
|
40
|
-
return `${this._prefix}:idx:${normalize_path(parent)}`;
|
|
41
|
-
}
|
|
42
|
-
/** @internal */
|
|
43
|
-
_split(path) {
|
|
44
|
-
const full = normalize_path(path);
|
|
45
|
-
const i = full.lastIndexOf('/');
|
|
46
|
-
if (i === -1) {
|
|
47
|
-
return { parent: '', full };
|
|
48
|
-
}
|
|
49
|
-
return { parent: full.slice(0, i), full };
|
|
40
|
+
return `${this._prefix}:idx:${(0, lib_1.normalize_path)(parent)}`;
|
|
50
41
|
}
|
|
51
42
|
/**
|
|
52
43
|
* Lee el valor de un documento.
|
|
@@ -56,38 +47,62 @@ class RedisEngine {
|
|
|
56
47
|
return this._client.get(this._doc_key(path));
|
|
57
48
|
}
|
|
58
49
|
/**
|
|
59
|
-
* Escribe el valor y
|
|
60
|
-
*
|
|
50
|
+
* Escribe el valor y su entrada de índice en una sola operación; `score` fija el orden
|
|
51
|
+
* de `list` (por defecto, la hora de escritura).
|
|
52
|
+
* Writes the value and its index entry in a single operation; `score` drives `list`
|
|
53
|
+
* ordering (write time by default).
|
|
61
54
|
*/
|
|
62
|
-
async set(path, value) {
|
|
63
|
-
const { parent
|
|
64
|
-
|
|
65
|
-
|
|
55
|
+
async set(path, value, score) {
|
|
56
|
+
const { parent } = (0, lib_1.split_path)(path);
|
|
57
|
+
const full = (0, lib_1.normalize_path)(path);
|
|
58
|
+
const doc_key = this._doc_key(full);
|
|
59
|
+
const idx_key = this._idx_key(parent);
|
|
60
|
+
const rank = score ?? Date.now();
|
|
61
|
+
const pipeline = this._client.pipeline?.();
|
|
62
|
+
if (pipeline) {
|
|
63
|
+
pipeline.set(doc_key, value);
|
|
64
|
+
pipeline.zadd(idx_key, rank, full);
|
|
65
|
+
await pipeline.exec();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
await this._client.set(doc_key, value);
|
|
69
|
+
await this._client.zadd(idx_key, rank, full);
|
|
70
|
+
}
|
|
66
71
|
}
|
|
67
72
|
/**
|
|
68
|
-
* Elimina el doc, su índice y todo el sub-árbol.
|
|
69
|
-
* Deletes the doc, its index, and the entire subtree.
|
|
73
|
+
* Elimina el doc, su entrada de índice y todo el sub-árbol.
|
|
74
|
+
* Deletes the doc, its index entry, and the entire subtree.
|
|
70
75
|
*/
|
|
71
76
|
async unset(path) {
|
|
72
|
-
const { parent
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
const { parent } = (0, lib_1.split_path)(path);
|
|
78
|
+
const full = (0, lib_1.normalize_path)(path);
|
|
79
|
+
const pipeline = this._client.pipeline?.();
|
|
80
|
+
if (pipeline) {
|
|
81
|
+
pipeline.del(this._doc_key(full));
|
|
82
|
+
pipeline.zrem(this._idx_key(parent), full);
|
|
83
|
+
await pipeline.exec();
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
await this._client.del(this._doc_key(full));
|
|
87
|
+
await this._client.zrem(this._idx_key(parent), full);
|
|
88
|
+
}
|
|
89
|
+
await Promise.all([
|
|
90
|
+
this._delete_pattern(`${this._prefix}:doc:${full}/*`),
|
|
91
|
+
this._delete_pattern(`${this._prefix}:idx:${full}`),
|
|
92
|
+
this._delete_pattern(`${this._prefix}:idx:${full}/*`),
|
|
93
|
+
]);
|
|
78
94
|
return true;
|
|
79
95
|
}
|
|
80
96
|
/**
|
|
81
|
-
* Lista valores de los hijos directos, ordenados por
|
|
82
|
-
* Lists direct children values ordered by
|
|
97
|
+
* Lista valores de los hijos directos, ordenados por score DESC en dos round-trips.
|
|
98
|
+
* Lists direct children values ordered by score DESC in two round-trips.
|
|
83
99
|
*/
|
|
84
100
|
async list(path, offset = 0, limit = 50) {
|
|
85
|
-
const
|
|
86
|
-
const members = await this._client.zrevrange(this._idx_key(full), offset, offset + limit - 1);
|
|
101
|
+
const members = await this._client.zrevrange(this._idx_key(path), offset, offset + limit - 1);
|
|
87
102
|
if (members.length === 0) {
|
|
88
103
|
return [];
|
|
89
104
|
}
|
|
90
|
-
const raws = await this._client.mget(members.map((
|
|
105
|
+
const raws = await this._client.mget(members.map((member) => this._doc_key(member)));
|
|
91
106
|
return raws.filter((raw) => raw !== null);
|
|
92
107
|
}
|
|
93
108
|
/**
|
|
@@ -95,8 +110,7 @@ class RedisEngine {
|
|
|
95
110
|
* Counts direct children in O(1) via ZCARD.
|
|
96
111
|
*/
|
|
97
112
|
async count(path) {
|
|
98
|
-
|
|
99
|
-
return this._client.zcard(this._idx_key(full));
|
|
113
|
+
return this._client.zcard(this._idx_key(path));
|
|
100
114
|
}
|
|
101
115
|
/**
|
|
102
116
|
* Vacía todo el prefix del cliente.
|
|
@@ -114,7 +128,7 @@ class RedisEngine {
|
|
|
114
128
|
async _delete_pattern(pattern) {
|
|
115
129
|
let cursor = '0';
|
|
116
130
|
do {
|
|
117
|
-
const [next, batch] = await this._client.scan(cursor, 'MATCH', pattern, 'COUNT',
|
|
131
|
+
const [next, batch] = await this._client.scan(cursor, 'MATCH', pattern, 'COUNT', 500);
|
|
118
132
|
cursor = next;
|
|
119
133
|
if (batch.length > 0) {
|
|
120
134
|
await this._client.del(batch);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../src/lib/store/engine/lib/redis/index.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../src/lib/store/engine/lib/redis/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,7 +33,26 @@ interface S3EngineOptions {
|
|
|
33
33
|
* Default: `false` (no cache).
|
|
34
34
|
*/
|
|
35
35
|
cache?: false | CacheOptions;
|
|
36
|
+
/** Prefijos indexados simultáneamente en memoria. / Simultaneously in-memory indexed prefixes. */
|
|
37
|
+
cached?: number;
|
|
36
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Driver de persistencia con AWS S3.
|
|
41
|
+
*
|
|
42
|
+
* Para que `list`/`count` no recorran todo el prefijo en cada página mantiene un índice
|
|
43
|
+
* ordenado por prefijo (`SortedIndex`), acotado por LRU y respaldado en el objeto `.order`:
|
|
44
|
+
* ahí viven los scores explícitos que S3 no puede representar (`LastModified` es de sólo
|
|
45
|
+
* lectura), de modo que el orden cronológico sobrevive a los re-syncs igual que en los
|
|
46
|
+
* demás drivers. Si el objeto `.order` falta, el índice se reconstruye listando el prefijo
|
|
47
|
+
* una única vez y ordenando por `LastModified`.
|
|
48
|
+
*
|
|
49
|
+
* AWS S3 persistence driver. To keep `list`/`count` from walking the whole prefix on every
|
|
50
|
+
* page it maintains a per-prefix sorted index (`SortedIndex`), LRU-bounded and backed by the
|
|
51
|
+
* `.order` object: it holds the explicit scores S3 cannot represent (`LastModified` is
|
|
52
|
+
* read-only), so chronological order survives re-syncs just like on the other drivers. When
|
|
53
|
+
* `.order` is missing the index is rebuilt listing the prefix once and ordering by
|
|
54
|
+
* `LastModified`.
|
|
55
|
+
*/
|
|
37
56
|
export declare class S3Engine implements Engine {
|
|
38
57
|
private readonly _client;
|
|
39
58
|
private readonly _bucket;
|
|
@@ -41,6 +60,8 @@ export declare class S3Engine implements Engine {
|
|
|
41
60
|
private readonly _cache_opts;
|
|
42
61
|
/** @internal Caché local de documentos, con su timer de expiración. / Local cache of documents, with its expiration timer. */
|
|
43
62
|
private readonly _cache;
|
|
63
|
+
/** @internal Índices por prefijo, acotados por LRU. / Per-prefix indexes, LRU-bounded. */
|
|
64
|
+
private readonly _indexes;
|
|
44
65
|
constructor(options: S3EngineOptions);
|
|
45
66
|
private _key;
|
|
46
67
|
/**
|
|
@@ -55,11 +76,33 @@ export declare class S3Engine implements Engine {
|
|
|
55
76
|
* Replaces the previous timer when the key was already cached so timers don't pile up.
|
|
56
77
|
*/
|
|
57
78
|
private _cache_set;
|
|
79
|
+
/**
|
|
80
|
+
* @internal
|
|
81
|
+
* Índice del prefijo: de la caché, del objeto `.order` o reconstruido listando el prefijo
|
|
82
|
+
* una sola vez y ordenando por `LastModified`.
|
|
83
|
+
* Prefix index: from the cache, from the `.order` object or rebuilt listing the prefix
|
|
84
|
+
* once and ordering by `LastModified`.
|
|
85
|
+
*/
|
|
86
|
+
private _index;
|
|
58
87
|
get(key: string): Promise<string | null>;
|
|
59
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Escribe el valor y registra su score en el índice del prefijo, que S3 no puede
|
|
90
|
+
* derivar por sí solo (`LastModified` es de sólo lectura).
|
|
91
|
+
* Writes the value and records its score in the prefix index, which S3 cannot derive
|
|
92
|
+
* on its own (`LastModified` is read-only).
|
|
93
|
+
*/
|
|
94
|
+
set(key: string, value: string, score?: number): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Lista los valores de los hijos directos, ordenados por score DESC.
|
|
97
|
+
* Lists direct children values ordered by score DESC.
|
|
98
|
+
*/
|
|
60
99
|
list(path: string, offset?: number, limit?: number): Promise<string[]>;
|
|
61
100
|
delete_prefix(prefix: string): Promise<number>;
|
|
62
101
|
unset(path: string): Promise<boolean>;
|
|
102
|
+
/**
|
|
103
|
+
* Cuenta hijos directos desde el índice del prefijo.
|
|
104
|
+
* Counts direct children from the prefix index.
|
|
105
|
+
*/
|
|
63
106
|
count(path: string): Promise<number>;
|
|
64
107
|
clear(): Promise<void>;
|
|
65
108
|
}
|