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