@arcaelas/whatsapp 4.5.0 → 6.0.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 (106) hide show
  1. package/README.md +282 -239
  2. package/build/cjs/decorators.js +0 -1
  3. package/build/cjs/index.d.ts +6 -4
  4. package/build/cjs/index.js +22 -3
  5. package/build/cjs/lib/bot/decorator.d.ts +2 -0
  6. package/build/cjs/lib/bot/decorator.js +6 -1
  7. package/build/cjs/lib/bot/decorators.d.ts +2 -2
  8. package/build/cjs/lib/bot/decorators.js +4 -4
  9. package/build/cjs/lib/bot/index.js +0 -1
  10. package/build/cjs/lib/chat/index.d.ts +381 -204
  11. package/build/cjs/lib/chat/index.js +243 -212
  12. package/build/cjs/lib/contact/index.d.ts +162 -179
  13. package/build/cjs/lib/contact/index.js +96 -191
  14. package/build/cjs/lib/internal.d.ts +40 -0
  15. package/build/cjs/lib/internal.js +38 -0
  16. package/build/cjs/lib/message/index.d.ts +468 -289
  17. package/build/cjs/lib/message/index.js +871 -743
  18. package/build/cjs/lib/status/index.d.ts +60 -70
  19. package/build/cjs/lib/status/index.js +106 -112
  20. package/build/cjs/lib/store/engine/index.d.ts +35 -7
  21. package/build/cjs/lib/store/engine/index.js +6 -4
  22. package/build/cjs/lib/store/engine/lib/file_system/index.d.ts +48 -8
  23. package/build/cjs/lib/store/engine/lib/file_system/index.js +117 -66
  24. package/build/cjs/lib/store/engine/lib/index.d.ts +112 -0
  25. package/build/cjs/lib/store/engine/lib/index.js +212 -0
  26. package/build/cjs/lib/store/engine/lib/redis/index.d.ts +44 -15
  27. package/build/cjs/lib/store/engine/lib/redis/index.js +75 -43
  28. package/build/cjs/lib/store/engine/lib/s3/index.d.ts +44 -1
  29. package/build/cjs/lib/store/engine/lib/s3/index.js +112 -65
  30. package/build/cjs/lib/store/engine/lib/sqlite/index.d.ts +110 -0
  31. package/build/cjs/lib/store/engine/lib/sqlite/index.js +132 -0
  32. package/build/cjs/lib/store/index.d.ts +7 -3
  33. package/build/cjs/lib/store/index.js +14 -5
  34. package/build/cjs/lib/whatsapp/index.d.ts +106 -68
  35. package/build/cjs/lib/whatsapp/index.js +393 -167
  36. package/build/esm/decorators.js +0 -1
  37. package/build/esm/index.d.ts +6 -4
  38. package/build/esm/index.js +5 -3
  39. package/build/esm/lib/bot/decorator.d.ts +2 -0
  40. package/build/esm/lib/bot/decorator.js +6 -1
  41. package/build/esm/lib/bot/decorators.d.ts +2 -2
  42. package/build/esm/lib/bot/decorators.js +4 -4
  43. package/build/esm/lib/bot/index.js +0 -1
  44. package/build/esm/lib/chat/index.d.ts +381 -204
  45. package/build/esm/lib/chat/index.js +243 -212
  46. package/build/esm/lib/contact/index.d.ts +162 -179
  47. package/build/esm/lib/contact/index.js +96 -190
  48. package/build/esm/lib/internal.d.ts +40 -0
  49. package/build/esm/lib/internal.js +34 -0
  50. package/build/esm/lib/message/index.d.ts +468 -289
  51. package/build/esm/lib/message/index.js +866 -738
  52. package/build/esm/lib/status/index.d.ts +60 -70
  53. package/build/esm/lib/status/index.js +105 -111
  54. package/build/esm/lib/store/engine/index.d.ts +35 -7
  55. package/build/esm/lib/store/engine/index.js +4 -3
  56. package/build/esm/lib/store/engine/lib/file_system/index.d.ts +48 -8
  57. package/build/esm/lib/store/engine/lib/file_system/index.js +117 -66
  58. package/build/esm/lib/store/engine/lib/index.d.ts +112 -0
  59. package/build/esm/lib/store/engine/lib/index.js +205 -0
  60. package/build/esm/lib/store/engine/lib/redis/index.d.ts +44 -15
  61. package/build/esm/lib/store/engine/lib/redis/index.js +73 -41
  62. package/build/esm/lib/store/engine/lib/s3/index.d.ts +44 -1
  63. package/build/esm/lib/store/engine/lib/s3/index.js +111 -64
  64. package/build/esm/lib/store/engine/lib/sqlite/index.d.ts +110 -0
  65. package/build/esm/lib/store/engine/lib/sqlite/index.js +128 -0
  66. package/build/esm/lib/store/index.d.ts +7 -3
  67. package/build/esm/lib/store/index.js +13 -5
  68. package/build/esm/lib/whatsapp/index.d.ts +106 -68
  69. package/build/esm/lib/whatsapp/index.js +395 -169
  70. package/package.json +25 -6
  71. package/build/cjs/decorators.js.map +0 -1
  72. package/build/cjs/index.js.map +0 -1
  73. package/build/cjs/lib/bot/decorator.js.map +0 -1
  74. package/build/cjs/lib/bot/decorators.js.map +0 -1
  75. package/build/cjs/lib/bot/index.js.map +0 -1
  76. package/build/cjs/lib/chat/index.js.map +0 -1
  77. package/build/cjs/lib/contact/index.js.map +0 -1
  78. package/build/cjs/lib/message/index.js.map +0 -1
  79. package/build/cjs/lib/status/index.js.map +0 -1
  80. package/build/cjs/lib/store/engine/index.js.map +0 -1
  81. package/build/cjs/lib/store/engine/lib/file_system/index.js.map +0 -1
  82. package/build/cjs/lib/store/engine/lib/redis/index.js.map +0 -1
  83. package/build/cjs/lib/store/engine/lib/s3/index.js.map +0 -1
  84. package/build/cjs/lib/store/index.js.map +0 -1
  85. package/build/cjs/lib/whatsapp/index.js.map +0 -1
  86. package/build/cjs/test.d.ts +0 -1
  87. package/build/cjs/test.js +0 -71
  88. package/build/cjs/test.js.map +0 -1
  89. package/build/esm/decorators.js.map +0 -1
  90. package/build/esm/index.js.map +0 -1
  91. package/build/esm/lib/bot/decorator.js.map +0 -1
  92. package/build/esm/lib/bot/decorators.js.map +0 -1
  93. package/build/esm/lib/bot/index.js.map +0 -1
  94. package/build/esm/lib/chat/index.js.map +0 -1
  95. package/build/esm/lib/contact/index.js.map +0 -1
  96. package/build/esm/lib/message/index.js.map +0 -1
  97. package/build/esm/lib/status/index.js.map +0 -1
  98. package/build/esm/lib/store/engine/index.js.map +0 -1
  99. package/build/esm/lib/store/engine/lib/file_system/index.js.map +0 -1
  100. package/build/esm/lib/store/engine/lib/redis/index.js.map +0 -1
  101. package/build/esm/lib/store/engine/lib/s3/index.js.map +0 -1
  102. package/build/esm/lib/store/index.js.map +0 -1
  103. package/build/esm/lib/whatsapp/index.js.map +0 -1
  104. package/build/esm/test.d.ts +0 -1
  105. package/build/esm/test.js +0 -66
  106. package/build/esm/test.js.map +0 -1
@@ -1,85 +1,75 @@
1
1
  /**
2
2
  * @file status/index.ts
3
- * @description Entidad `Feed`representa una publicación del status broadcast
4
- * (`status@broadcast`). Análoga a `Message` pero acotada al ciclo de vida de un
5
- * status (24h, no se cita, no se edita, sin starring/forward).
6
- * Status broadcast entry. Analogous to `Message` but scoped to the status
7
- * lifecycle (24h TTL, no quoting, no editing, no starring/forward).
3
+ * @description Entidad Feed — publicación del status broadcast (`status@broadcast`) como
4
+ * subclase de Message: hereda author/chat/content/stream y anula lo que un status no soporta.
5
+ * Feed entity status broadcast post as a Message subclass: inherits
6
+ * author/chat/content/stream and voids what a status does not support.
8
7
  */
9
- import { type WAMessage } from 'baileys';
10
- import { Readable } from 'node:stream';
11
- import { Contact } from '../../lib/contact';
8
+ import type { WAMessage } from 'baileys';
9
+ import { Message } from '../../lib/message';
12
10
  import type { WhatsApp } from '../../lib/whatsapp';
13
- /** Tipos soportados por un status broadcast. / Status broadcast supported types. */
14
- export type FeedType = 'text' | 'image' | 'video' | 'audio';
15
- /**
16
- * Documento persistido del status.
17
- * Persisted status document.
18
- */
19
- export interface IFeedRaw {
20
- id: string;
21
- author_jid: string;
22
- type: FeedType;
23
- caption: string;
24
- mime: string;
25
- created_at: number;
26
- expires_at: number;
27
- viewed: boolean;
28
- raw: WAMessage;
29
- }
30
11
  /** Vida útil del status: 24 horas en ms. / Status lifetime: 24h in ms. */
31
12
  export declare const TTL_MS: number;
32
13
  /**
33
- * Status broadcast una publicación del feed `status@broadcast` con duración 24h.
34
- *
35
- * Status broadcast entry — a `status@broadcast` post with a 24h lifetime.
14
+ * Publicación del status broadcast. El documento del status se adapta al shape de
15
+ * Message en el constructor (`cid` fijo a `status@broadcast`, `author` desde
16
+ * `author_jid`, `deleted_at` desde `expires_at`), así los getters heredados aplican
17
+ * tal cual.
18
+ * Status broadcast post. The status document is adapted to the Message shape in the
19
+ * constructor (`cid` pinned to `status@broadcast`, `author` from `author_jid`,
20
+ * `deleted_at` from `expires_at`), so inherited getters apply as-is.
36
21
  */
37
- export default class Feed {
38
- /** @internal */
39
- protected readonly _wa: WhatsApp;
40
- /** @internal */
41
- protected readonly _doc: IFeedRaw;
42
- /** @internal Cache de la promesa de `author()` para evitar engine round-trips repetidos. */
43
- private _author_cache;
44
- constructor(options: {
45
- wa: WhatsApp;
46
- doc: IFeedRaw;
22
+ export declare class Feed extends Message {
23
+ constructor(wa: WhatsApp, doc: {
24
+ id: string;
25
+ author_jid: string;
26
+ type: 'text' | 'image' | 'video' | 'audio';
27
+ caption: string;
28
+ mime: string;
29
+ created_at: number;
30
+ expires_at: number;
31
+ viewed: boolean;
32
+ raw: WAMessage;
47
33
  });
48
- /** Identificador del status (mid). / Status id (mid). */
49
- get id(): string;
50
- /** Tipo de contenido. / Content type. */
51
- get type(): FeedType;
52
34
  /** true si ya enviamos read receipt sobre este status. / true once a read receipt was sent. */
53
35
  get viewed(): boolean;
54
- /** Texto / caption del status. / Status text or caption. */
55
- get caption(): string;
56
- /** Epoch ms de publicación. / Publication epoch ms. */
57
- get created_at(): number;
58
- /** Epoch ms de expiración (created_at + 24h). / Expiration epoch ms (created_at + 24h). */
59
- get expires_at(): number;
60
- /**
61
- * Resuelve el autor del status. Memoizado a nivel de instancia: la primera
62
- * llamada va al engine vía `wa.Contact.get`; las siguientes devuelven la misma
63
- * instancia sin volver a leer.
64
- * Resolves the status author. Instance-memoized: first call hits the engine
65
- * via `wa.Contact.get`; subsequent calls return the cached instance.
66
- */
67
- author(): Promise<Contact>;
68
- /**
69
- * Stream progresivo del contenido. Para texto envuelve el caption; para media
70
- * lee del cache del engine y, si falta, descarga desde baileys.
71
- * Progressive content stream. For text wraps the caption; for media reads the
72
- * engine cache and falls back to baileys download.
73
- */
74
- stream(): Promise<Readable>;
75
- /**
76
- * Acumula el stream del status en un Buffer.
77
- * Drains the status stream into a Buffer.
78
- */
79
- content(): Promise<Buffer>;
80
36
  /**
81
- * Marca el status como visto enviando read receipt. Persiste `viewed = true`.
82
- * Marks the status as seen sending a read receipt. Persists `viewed = true`.
37
+ * Marca el status como visto enviando read receipt y persiste `viewed`.
38
+ * Marks the status as seen sending a read receipt and persists `viewed`.
39
+ *
40
+ * @returns true si se envió / true when sent
83
41
  */
84
42
  view(): Promise<boolean>;
43
+ /** Un status marca visto con `view()`. / A status marks seen via `view()`. */
44
+ seen(): Promise<boolean>;
45
+ /** No soportado en un status. / Unsupported on a status. */
46
+ message(): Promise<never>;
47
+ /** No soportado en un status. / Unsupported on a status. */
48
+ react(): Promise<never>;
49
+ /** No soportado en un status. / Unsupported on a status. */
50
+ star(): Promise<never>;
51
+ /** No soportado en un status. / Unsupported on a status. */
52
+ edit(): Promise<never>;
53
+ /** No soportado en un status. / Unsupported on a status. */
54
+ forward(): Promise<never>;
55
+ /** No soportado en un status. / Unsupported on a status. */
56
+ delete(): Promise<never>;
57
+ /** No soportado en un status. / Unsupported on a status. */
58
+ text(): Promise<never>;
59
+ /** No soportado en un status. / Unsupported on a status. */
60
+ image(): Promise<never>;
61
+ /** No soportado en un status. / Unsupported on a status. */
62
+ video(): Promise<never>;
63
+ /** No soportado en un status. / Unsupported on a status. */
64
+ audio(): Promise<never>;
65
+ /** No soportado en un status. / Unsupported on a status. */
66
+ location(): Promise<never>;
67
+ /** No soportado en un status. / Unsupported on a status. */
68
+ poll(): Promise<never>;
69
+ /** No soportado en un status. / Unsupported on a status. */
70
+ document(): Promise<never>;
71
+ /** No soportado en un status. / Unsupported on a status. */
72
+ vcard(): Promise<never>;
73
+ /** No soportado en un status. / Unsupported on a status. */
74
+ event(): Promise<never>;
85
75
  }
@@ -1,137 +1,131 @@
1
1
  "use strict";
2
2
  /**
3
3
  * @file status/index.ts
4
- * @description Entidad `Feed`representa una publicación del status broadcast
5
- * (`status@broadcast`). Análoga a `Message` pero acotada al ciclo de vida de un
6
- * status (24h, no se cita, no se edita, sin starring/forward).
7
- * Status broadcast entry. Analogous to `Message` but scoped to the status
8
- * lifecycle (24h TTL, no quoting, no editing, no starring/forward).
4
+ * @description Entidad Feed — publicación del status broadcast (`status@broadcast`) como
5
+ * subclase de Message: hereda author/chat/content/stream y anula lo que un status no soporta.
6
+ * Feed entity status broadcast post as a Message subclass: inherits
7
+ * author/chat/content/stream and voids what a status does not support.
9
8
  */
10
9
  Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.TTL_MS = void 0;
12
- const baileys_1 = require("baileys");
13
- const node_stream_1 = require("node:stream");
10
+ exports.Feed = exports.TTL_MS = void 0;
11
+ const internal_1 = require("../../lib/internal");
12
+ const message_1 = require("../../lib/message");
14
13
  const store_1 = require("../../lib/store");
15
14
  /** Vida útil del status: 24 horas en ms. / Status lifetime: 24h in ms. */
16
15
  exports.TTL_MS = 24 * 60 * 60 * 1000;
17
16
  /**
18
- * Status broadcast una publicación del feed `status@broadcast` con duración 24h.
19
- *
20
- * Status broadcast entry — a `status@broadcast` post with a 24h lifetime.
17
+ * Publicación del status broadcast. El documento del status se adapta al shape de
18
+ * Message en el constructor (`cid` fijo a `status@broadcast`, `author` desde
19
+ * `author_jid`, `deleted_at` desde `expires_at`), así los getters heredados aplican
20
+ * tal cual.
21
+ * Status broadcast post. The status document is adapted to the Message shape in the
22
+ * constructor (`cid` pinned to `status@broadcast`, `author` from `author_jid`,
23
+ * `deleted_at` from `expires_at`), so inherited getters apply as-is.
21
24
  */
22
- class Feed {
23
- constructor(options) {
24
- /** @internal Cache de la promesa de `author()` para evitar engine round-trips repetidos. */
25
- this._author_cache = null;
26
- this._wa = options.wa;
27
- this._doc = options.doc;
28
- }
29
- /** Identificador del status (mid). / Status id (mid). */
30
- get id() {
31
- return this._doc.id;
32
- }
33
- /** Tipo de contenido. / Content type. */
34
- get type() {
35
- return this._doc.type;
25
+ class Feed extends message_1.Message {
26
+ constructor(wa, doc) {
27
+ super(wa, {
28
+ ...doc,
29
+ cid: 'status@broadcast',
30
+ mid: null,
31
+ me: false,
32
+ author: doc.author_jid,
33
+ status: 1,
34
+ starred: false,
35
+ forwarded: false,
36
+ deleted_at: doc.expires_at,
37
+ edited: false,
38
+ });
36
39
  }
37
40
  /** true si ya enviamos read receipt sobre este status. / true once a read receipt was sent. */
38
41
  get viewed() {
39
- return this._doc.viewed;
40
- }
41
- /** Texto / caption del status. / Status text or caption. */
42
- get caption() {
43
- return this._doc.caption;
44
- }
45
- /** Epoch ms de publicación. / Publication epoch ms. */
46
- get created_at() {
47
- return this._doc.created_at;
48
- }
49
- /** Epoch ms de expiración (created_at + 24h). / Expiration epoch ms (created_at + 24h). */
50
- get expires_at() {
51
- return this._doc.expires_at;
52
- }
53
- /**
54
- * Resuelve el autor del status. Memoizado a nivel de instancia: la primera
55
- * llamada va al engine vía `wa.Contact.get`; las siguientes devuelven la misma
56
- * instancia sin volver a leer.
57
- * Resolves the status author. Instance-memoized: first call hits the engine
58
- * via `wa.Contact.get`; subsequent calls return the cached instance.
59
- */
60
- async author() {
61
- return (this._author_cache ??= (async () => {
62
- const { _wa, _doc } = this;
63
- const fetched = await _wa.Contact.get(_doc.author_jid);
64
- return (fetched ??
65
- new _wa.Contact({
66
- id: _doc.author_jid,
67
- lid: null,
68
- name: null,
69
- notify: null,
70
- verified_name: null,
71
- img_url: null,
72
- status: null,
73
- }, new _wa.Chat({
74
- id: _doc.author_jid,
75
- name: _doc.author_jid.split('@')[0],
76
- })));
77
- })());
78
- }
79
- /**
80
- * Stream progresivo del contenido. Para texto envuelve el caption; para media
81
- * lee del cache del engine y, si falta, descarga desde baileys.
82
- * Progressive content stream. For text wraps the caption; for media reads the
83
- * engine cache and falls back to baileys download.
84
- */
85
- async stream() {
86
- const { _wa, _doc } = this;
87
- if (_doc.type === 'text') {
88
- return node_stream_1.Readable.from(Buffer.from(_doc.caption, 'utf-8'));
89
- }
90
- const cached = (0, store_1.deserialize)(await _wa.engine.get(`/status/${_doc.id}/content`));
91
- if (cached?.data) {
92
- return node_stream_1.Readable.from(Buffer.from(cached.data, 'base64'));
93
- }
94
- if (_wa._socket) {
95
- try {
96
- return (await (0, baileys_1.downloadMediaMessage)(_doc.raw, 'stream', {}));
97
- }
98
- catch {
99
- /* fallback empty */
100
- }
101
- }
102
- return node_stream_1.Readable.from(Buffer.alloc(0));
103
- }
104
- /**
105
- * Acumula el stream del status en un Buffer.
106
- * Drains the status stream into a Buffer.
107
- */
108
- async content() {
109
- const chunks = [];
110
- for await (const chunk of await this.stream()) {
111
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
112
- }
113
- return Buffer.concat(chunks);
42
+ return this._raw.viewed ?? false;
114
43
  }
115
44
  /**
116
- * Marca el status como visto enviando read receipt. Persiste `viewed = true`.
117
- * Marks the status as seen sending a read receipt. Persists `viewed = true`.
45
+ * Marca el status como visto enviando read receipt y persiste `viewed`.
46
+ * Marks the status as seen sending a read receipt and persists `viewed`.
47
+ *
48
+ * @returns true si se envió / true when sent
118
49
  */
119
50
  async view() {
120
- const { _wa, _doc } = this;
121
51
  let ok = false;
122
- if (_wa._socket) {
123
- if (!_doc.viewed) {
124
- await _wa._socket.readMessages([
125
- { remoteJid: 'status@broadcast', id: _doc.id, participant: _doc.author_jid },
52
+ const socket = (0, internal_1.internals)(this._wa).socket;
53
+ if (socket) {
54
+ if (!this.viewed) {
55
+ await socket.readMessages([
56
+ { remoteJid: 'status@broadcast', id: this._raw.id, participant: this._raw.author },
126
57
  ]);
127
- _doc.viewed = true;
128
- await _wa.engine.set(`/status/${_doc.id}`, (0, store_1.serialize)(_doc));
58
+ this._raw.viewed = true;
59
+ await this._wa.engine.set(`/status/${this._raw.id}`, (0, store_1.serialize)(this._raw));
129
60
  }
130
- _wa._event.emit('feed:updated', this, _wa);
61
+ this._wa.emit('feed:updated', this, this._wa);
131
62
  ok = true;
132
63
  }
133
64
  return ok;
134
65
  }
66
+ /** Un status marca visto con `view()`. / A status marks seen via `view()`. */
67
+ async seen() {
68
+ return this.view();
69
+ }
70
+ /** No soportado en un status. / Unsupported on a status. */
71
+ async message() {
72
+ throw new Error('ERR_FEED_UNSUPPORTED');
73
+ }
74
+ /** No soportado en un status. / Unsupported on a status. */
75
+ async react() {
76
+ throw new Error('ERR_FEED_UNSUPPORTED');
77
+ }
78
+ /** No soportado en un status. / Unsupported on a status. */
79
+ async star() {
80
+ throw new Error('ERR_FEED_UNSUPPORTED');
81
+ }
82
+ /** No soportado en un status. / Unsupported on a status. */
83
+ async edit() {
84
+ throw new Error('ERR_FEED_UNSUPPORTED');
85
+ }
86
+ /** No soportado en un status. / Unsupported on a status. */
87
+ async forward() {
88
+ throw new Error('ERR_FEED_UNSUPPORTED');
89
+ }
90
+ /** No soportado en un status. / Unsupported on a status. */
91
+ async delete() {
92
+ throw new Error('ERR_FEED_UNSUPPORTED');
93
+ }
94
+ /** No soportado en un status. / Unsupported on a status. */
95
+ async text() {
96
+ throw new Error('ERR_FEED_UNSUPPORTED');
97
+ }
98
+ /** No soportado en un status. / Unsupported on a status. */
99
+ async image() {
100
+ throw new Error('ERR_FEED_UNSUPPORTED');
101
+ }
102
+ /** No soportado en un status. / Unsupported on a status. */
103
+ async video() {
104
+ throw new Error('ERR_FEED_UNSUPPORTED');
105
+ }
106
+ /** No soportado en un status. / Unsupported on a status. */
107
+ async audio() {
108
+ throw new Error('ERR_FEED_UNSUPPORTED');
109
+ }
110
+ /** No soportado en un status. / Unsupported on a status. */
111
+ async location() {
112
+ throw new Error('ERR_FEED_UNSUPPORTED');
113
+ }
114
+ /** No soportado en un status. / Unsupported on a status. */
115
+ async poll() {
116
+ throw new Error('ERR_FEED_UNSUPPORTED');
117
+ }
118
+ /** No soportado en un status. / Unsupported on a status. */
119
+ async document() {
120
+ throw new Error('ERR_FEED_UNSUPPORTED');
121
+ }
122
+ /** No soportado en un status. / Unsupported on a status. */
123
+ async vcard() {
124
+ throw new Error('ERR_FEED_UNSUPPORTED');
125
+ }
126
+ /** No soportado en un status. / Unsupported on a status. */
127
+ async event() {
128
+ throw new Error('ERR_FEED_UNSUPPORTED');
129
+ }
135
130
  }
136
- exports.default = Feed;
137
- //# sourceMappingURL=index.js.map
131
+ exports.Feed = Feed;
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * @file store/engine/index.ts
3
- * @description Contrato del motor de persistencia (string-based) y barrel de drivers.
4
- * Engine contract (string-based) and drivers barrel.
3
+ * @description Contrato del motor de persistencia (string-based), utilidades compartidas
4
+ * por los drivers y barrel de implementaciones.
5
+ * Engine contract (string-based), shared driver utilities and implementations barrel.
5
6
  */
6
7
  /**
7
8
  * Contrato de persistencia key-value de strings. El engine no conoce JSON; la serialización
@@ -12,24 +13,51 @@
12
13
  *
13
14
  * Reglas / Rules:
14
15
  * - Paths se normalizan quitando slashes redundantes. / Paths strip redundant slashes.
15
- * - `set` refresca el mtime (drives `list` order). / `set` refreshes mtime.
16
+ * - `set` fija el score de orden: el `score` explícito cuando llega, o la hora de escritura.
17
+ * / `set` fixes the ordering score: the explicit `score` when given, else write time.
16
18
  * - `unset` hace cascade sobre el sub-árbol. / `unset` cascades the subtree.
17
- * - `list` solo devuelve hijos directos ordenados por mtime DESC. / `list` yields direct children, mtime DESC.
19
+ * - `list` solo devuelve hijos directos ordenados por score DESC. / `list` yields direct children, score DESC.
20
+ * - `list` y `count` cuestan O(limit) amortizado: los drivers mantienen un índice ordenado
21
+ * por directorio en vez de recorrer y re-ordenar el padre en cada página (ver `SortedIndex`).
22
+ * / `list` and `count` cost O(limit) amortized: drivers keep a per-directory sorted index
23
+ * instead of scanning and re-sorting the parent on every page.
18
24
  */
19
25
  export interface Engine {
20
26
  /** Lee un valor por path. Retorna null si no existe. / Reads a value by path; null if missing. */
21
27
  get(path: string): Promise<string | null>;
22
- /** Escribe un valor. Refresca el mtime. / Writes a value. Refreshes mtime. */
23
- set(path: string, value: string): Promise<void>;
28
+ /**
29
+ * Escribe un valor. `score` fija el orden de `list` (epoch ms del documento, ej. `created_at`);
30
+ * sin él se usa la hora de escritura — los re-syncs que reescriben documentos históricos DEBEN
31
+ * pasar el score para no destruir la cronología.
32
+ * Writes a value. `score` drives `list` ordering (document epoch ms, e.g. `created_at`);
33
+ * without it write time is used — re-syncs rewriting historical documents MUST pass the
34
+ * score to preserve chronology.
35
+ */
36
+ set(path: string, value: string, score?: number): Promise<void>;
24
37
  /** Elimina el valor y todos sus descendientes. Idempotente. / Cascade delete. Idempotent. */
25
38
  unset(path: string): Promise<boolean>;
26
- /** Lista valores de los hijos directos, paginados por mtime DESC. / Lists direct children values, mtime DESC. */
39
+ /** Lista valores de los hijos directos, paginados por score DESC. / Lists direct children values, score DESC. */
27
40
  list(path: string, offset?: number, limit?: number): Promise<string[]>;
28
41
  /** Cuenta hijos directos sin leer los valores. / Counts direct children without loading values. */
29
42
  count(path: string): Promise<number>;
30
43
  /** Vacía completamente el almacén. / Clears the entire store. */
31
44
  clear(): Promise<void>;
45
+ /**
46
+ * Lee un binario por path. Opcional: un driver que no lo implemente sigue siendo válido y
47
+ * la librería cae al documento serializado.
48
+ * Reads a binary by path. Optional: a driver that does not implement it stays valid and the
49
+ * library falls back to the serialized document.
50
+ */
51
+ get_buffer?(path: string): Promise<Buffer | null>;
52
+ /**
53
+ * Escribe un binario sin pasar por JSON ni base64 (un 33% menos de peso y sin parseo para
54
+ * leerlo). Opcional, igual que `get_buffer`.
55
+ * Writes a binary without JSON nor base64 (33% less weight and no parsing to read it back).
56
+ * Optional, just like `get_buffer`.
57
+ */
58
+ set_buffer?(path: string, data: Buffer, score?: number): Promise<void>;
32
59
  }
33
60
  export { FileSystemEngine } from '../../../lib/store/engine/lib/file_system';
34
61
  export { RedisEngine, type RedisClient } from '../../../lib/store/engine/lib/redis';
35
62
  export { S3Engine } from '../../../lib/store/engine/lib/s3';
63
+ export { SQLiteEngine, type SQLiteDatabase } from '../../../lib/store/engine/lib/sqlite';
@@ -1,15 +1,17 @@
1
1
  "use strict";
2
2
  /**
3
3
  * @file store/engine/index.ts
4
- * @description Contrato del motor de persistencia (string-based) y barrel de drivers.
5
- * Engine contract (string-based) and drivers barrel.
4
+ * @description Contrato del motor de persistencia (string-based), utilidades compartidas
5
+ * por los drivers y barrel de implementaciones.
6
+ * Engine contract (string-based), shared driver utilities and implementations barrel.
6
7
  */
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.S3Engine = exports.RedisEngine = exports.FileSystemEngine = void 0;
9
+ exports.SQLiteEngine = exports.S3Engine = exports.RedisEngine = exports.FileSystemEngine = void 0;
9
10
  var file_system_1 = require("../../../lib/store/engine/lib/file_system");
10
11
  Object.defineProperty(exports, "FileSystemEngine", { enumerable: true, get: function () { return file_system_1.FileSystemEngine; } });
11
12
  var redis_1 = require("../../../lib/store/engine/lib/redis");
12
13
  Object.defineProperty(exports, "RedisEngine", { enumerable: true, get: function () { return redis_1.RedisEngine; } });
13
14
  var s3_1 = require("../../../lib/store/engine/lib/s3");
14
15
  Object.defineProperty(exports, "S3Engine", { enumerable: true, get: function () { return s3_1.S3Engine; } });
15
- //# sourceMappingURL=index.js.map
16
+ var sqlite_1 = require("../../../lib/store/engine/lib/sqlite");
17
+ Object.defineProperty(exports, "SQLiteEngine", { enumerable: true, get: function () { return sqlite_1.SQLiteEngine; } });
@@ -7,10 +7,22 @@ import type { Engine } from '../../../../../lib/store/engine';
7
7
  /**
8
8
  * Driver de persistencia en sistema de archivos.
9
9
  * Cada documento se almacena como `<base>/<path>/index.json` de modo que un recurso pueda
10
- * coexistir con sub-recursos anidados.
10
+ * coexistir con sub-recursos anidados. Las escrituras son atómicas (tmp + rename) y el score
11
+ * de orden viaja en el mtime del archivo.
12
+ *
13
+ * Para que `list`/`count` cuesten O(limit) mantiene un índice ordenado por directorio
14
+ * (`SortedIndex`), acotado por LRU y respaldado en `<dir>/.order`: al abrir un directorio
15
+ * carga ese archivo y sólo reconstruye con `readdir` + `stat` cuando el conteo no coincide.
16
+ * Asume un único proceso escritor sobre el directorio base.
11
17
  *
12
18
  * Filesystem persistence driver. Each document lives at `<base>/<path>/index.json` so a
13
- * resource can coexist with nested sub-resources.
19
+ * resource can coexist with nested sub-resources. Writes are atomic (tmp + rename) and the
20
+ * ordering score travels in the file mtime.
21
+ *
22
+ * To keep `list`/`count` at O(limit) it maintains a per-directory sorted index
23
+ * (`SortedIndex`), LRU-bounded and backed by `<dir>/.order`: opening a directory loads that
24
+ * file and only rebuilds via `readdir` + `stat` when the count does not match. Assumes a
25
+ * single writer process over the base directory.
14
26
  *
15
27
  * @example
16
28
  * const engine = new FileSystemEngine('/tmp/wa');
@@ -18,29 +30,47 @@ import type { Engine } from '../../../../../lib/store/engine';
18
30
  */
19
31
  export declare class FileSystemEngine implements Engine {
20
32
  private readonly _base;
21
- constructor(_base: string);
33
+ /** @internal Índices por directorio, acotados por LRU. / Per-directory indexes, LRU-bounded. */
34
+ private readonly _indexes;
35
+ /**
36
+ * @param _base - Directorio raíz del almacén / Store root directory
37
+ * @param cached - Directorios indexados simultáneamente en memoria / Simultaneously in-memory indexed directories
38
+ */
39
+ constructor(_base: string, cached?: number);
22
40
  /** @internal */
23
41
  private _dir;
24
42
  /** @internal */
25
43
  private _file;
44
+ /**
45
+ * @internal
46
+ * Índice del directorio: lo toma de la caché, del `.order` persistido (validando el conteo
47
+ * contra `readdir`) o lo reconstruye leyendo el mtime de cada hijo.
48
+ * Directory index: taken from the cache, from the persisted `.order` (validating the count
49
+ * against `readdir`) or rebuilt reading each child's mtime.
50
+ */
51
+ private _index;
52
+ /** @internal Escritura atómica: archivo temporal y rename sobre el destino. / Atomic write: temp file plus rename onto the target. */
53
+ private _write;
26
54
  /**
27
55
  * Lee el valor de un documento.
28
56
  * Reads a document's value.
29
57
  */
30
58
  get(path: string): Promise<string | null>;
31
59
  /**
32
- * Escribe el valor de un documento, creando los directorios necesarios.
33
- * Writes a document's value, creating directories as needed.
60
+ * Escribe el valor de un documento de forma atómica creando los directorios necesarios;
61
+ * con `score` fija el mtime del archivo (y por tanto el orden de `list`).
62
+ * Atomically writes a document's value creating directories as needed; `score` fixes the
63
+ * file mtime (and therefore `list` ordering).
34
64
  */
35
- set(path: string, value: string): Promise<void>;
65
+ set(path: string, value: string, score?: number): Promise<void>;
36
66
  /**
37
67
  * Elimina el documento y todos sus descendientes. Idempotente.
38
68
  * Deletes the document and every descendant. Idempotent.
39
69
  */
40
70
  unset(path: string): Promise<boolean>;
41
71
  /**
42
- * Lista los valores de los hijos directos, ordenados por mtime DESC.
43
- * Lists direct children values ordered by mtime DESC.
72
+ * Lista los valores de los hijos directos, ordenados por score DESC.
73
+ * Lists direct children values ordered by score DESC.
44
74
  */
45
75
  list(path: string, offset?: number, limit?: number): Promise<string[]>;
46
76
  /**
@@ -48,6 +78,16 @@ export declare class FileSystemEngine implements Engine {
48
78
  * Counts direct children with a valid document.
49
79
  */
50
80
  count(path: string): Promise<number>;
81
+ /**
82
+ * Lee el binario del documento, o null si no existe.
83
+ * Reads the document binary, or null when missing.
84
+ */
85
+ get_buffer(path: string): Promise<Buffer | null>;
86
+ /**
87
+ * Escribe el binario del documento como archivo crudo, sin JSON ni base64.
88
+ * Writes the document binary as a raw file, with no JSON nor base64.
89
+ */
90
+ set_buffer(path: string, data: Buffer, score?: number): Promise<void>;
51
91
  /**
52
92
  * Vacía completamente el almacén.
53
93
  * Clears the entire store.