@ravi-hq/ravi 0.6.1 → 0.6.2

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 (44) hide show
  1. package/README.md +8 -9
  2. package/dist/channels/email-trusted.d.ts +5 -5
  3. package/dist/channels/email-trusted.js +18 -18
  4. package/dist/channels/email-trusted.js.map +1 -1
  5. package/dist/channels/email.d.ts +12 -12
  6. package/dist/channels/email.js +22 -22
  7. package/dist/channels/email.js.map +1 -1
  8. package/dist/client.d.ts +18 -1
  9. package/dist/client.d.ts.map +1 -1
  10. package/dist/client.js +22 -1
  11. package/dist/client.js.map +1 -1
  12. package/dist/index.d.ts +4 -4
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +6 -6
  15. package/dist/index.js.map +1 -1
  16. package/dist/polling-pool.d.ts +17 -0
  17. package/dist/polling-pool.d.ts.map +1 -0
  18. package/dist/polling-pool.js +42 -0
  19. package/dist/polling-pool.js.map +1 -0
  20. package/dist/polling.d.ts +70 -0
  21. package/dist/polling.d.ts.map +1 -0
  22. package/dist/polling.js +208 -0
  23. package/dist/polling.js.map +1 -0
  24. package/dist/tools/contacts.d.ts.map +1 -1
  25. package/dist/tools/contacts.js +3 -4
  26. package/dist/tools/contacts.js.map +1 -1
  27. package/dist/tools/identity.d.ts.map +1 -1
  28. package/dist/tools/identity.js +4 -3
  29. package/dist/tools/identity.js.map +1 -1
  30. package/dist/types.d.ts +6 -4
  31. package/dist/types.d.ts.map +1 -1
  32. package/package.json +1 -1
  33. package/dist/channels/email-untrusted.d.ts +0 -133
  34. package/dist/channels/email-untrusted.d.ts.map +0 -1
  35. package/dist/channels/email-untrusted.js +0 -283
  36. package/dist/channels/email-untrusted.js.map +0 -1
  37. package/dist/sse-pool.d.ts +0 -18
  38. package/dist/sse-pool.d.ts.map +0 -1
  39. package/dist/sse-pool.js +0 -43
  40. package/dist/sse-pool.js.map +0 -1
  41. package/dist/sse.d.ts +0 -117
  42. package/dist/sse.d.ts.map +0 -1
  43. package/dist/sse.js +0 -301
  44. package/dist/sse.js.map +0 -1
package/dist/sse.d.ts DELETED
@@ -1,117 +0,0 @@
1
- import type { EmailEvent } from "./types.js";
2
- /** Callback invoked when a typed SSE event is received. */
3
- export type SSEEventHandler<T> = (event: T) => void;
4
- /** Options for constructing a {@link RaviSSEClient}. */
5
- export interface RaviSSEClientConfig {
6
- /** Base URL of the Ravi API (e.g. "https://api.ravi.dev"). */
7
- apiUrl: string;
8
- /** JWT bearer token for authentication (identity is embedded in JWT claims). */
9
- token: string;
10
- /**
11
- * Optional callback invoked when SSE receives a 401/403 response.
12
- * Return a fresh token to retry the connection, or `null` to stop.
13
- */
14
- onAuthFailure?: () => Promise<string | null>;
15
- }
16
- /**
17
- * Server-Sent Events client for the Ravi real-time event stream.
18
- *
19
- * Connects to `GET /api/events/stream/` and dispatches typed events
20
- * (email_owner, email_trusted, email_untrusted) to registered handlers. Identity scoping is embedded
21
- * in the JWT token (obtained via bind-identity). Automatically reconnects
22
- * with exponential backoff on connection loss and monitors server
23
- * heartbeats to detect stale connections.
24
- *
25
- * @example
26
- * ```ts
27
- * const sse = new RaviSSEClient({
28
- * apiUrl: "https://api.ravi.dev",
29
- * token: "ey...", // bound token with identity in JWT claims
30
- * });
31
- *
32
- * sse.onEmailOwner((event) => console.log("New email:", event.subject));
33
- * sse.connect();
34
- *
35
- * // Later...
36
- * sse.disconnect();
37
- * ```
38
- */
39
- export declare class RaviSSEClient {
40
- private apiUrl;
41
- private token;
42
- private controller;
43
- private reconnectDelay;
44
- private maxReconnectDelay;
45
- private lastEventId;
46
- private emailOwnerHandlers;
47
- private emailTrustedHandlers;
48
- private emailUntrustedHandlers;
49
- private reconnectHandlers;
50
- private running;
51
- private heartbeatTimeout;
52
- /** Expect a keepalive or data every 60s (server sends keepalive every 30s). */
53
- private heartbeatInterval;
54
- /** Flag set when the heartbeat timer aborts the connection. */
55
- private isHeartbeatAbort;
56
- /** Optional callback to attempt token refresh on 401/403. */
57
- private onAuthFailure?;
58
- constructor(config: RaviSSEClientConfig);
59
- /** Register a handler for email events from the identity owner. */
60
- onEmailOwner(handler: SSEEventHandler<EmailEvent>): void;
61
- /** Register a handler for email events from trusted senders. */
62
- onEmailTrusted(handler: SSEEventHandler<EmailEvent>): void;
63
- /** Register a handler for email events from untrusted senders. */
64
- onEmailUntrusted(handler: SSEEventHandler<EmailEvent>): void;
65
- /**
66
- * Register a handler that fires whenever the client reconnects after a
67
- * connection drop. Useful for re-fetching state that may have been missed
68
- * during the disconnection window.
69
- */
70
- onReconnect(handler: () => void): void;
71
- /**
72
- * Open the SSE connection and begin streaming events.
73
- *
74
- * The connection loop runs in the background and will automatically
75
- * reconnect on failure. Call {@link disconnect} to stop.
76
- */
77
- connect(): void;
78
- /**
79
- * Update the bearer token used for SSE connections.
80
- *
81
- * Takes effect on the next reconnection — the current connection
82
- * continues until it naturally drops or is aborted.
83
- */
84
- updateToken(token: string): void;
85
- /**
86
- * Gracefully close the SSE connection.
87
- *
88
- * Aborts any in-flight fetch, stops the heartbeat timer, and prevents
89
- * further reconnection attempts.
90
- */
91
- disconnect(): void;
92
- /**
93
- * Core connection loop. Opens a streaming fetch to the SSE endpoint,
94
- * parses the event stream, and dispatches events. On failure, waits
95
- * with exponential backoff before retrying.
96
- */
97
- private startConnection;
98
- /**
99
- * Parse the JSON data payload and dispatch to the appropriate typed handlers.
100
- *
101
- * Logs and skips events with malformed JSON. Handler errors are caught
102
- * individually so one broken handler does not prevent others from running.
103
- */
104
- private dispatchEvent;
105
- /**
106
- * Reset the heartbeat watchdog timer.
107
- *
108
- * Called whenever we receive any data from the server (keepalive comments,
109
- * event data, etc.). If no data arrives within {@link heartbeatInterval}ms,
110
- * the connection is assumed stale and the fetch is aborted to trigger
111
- * reconnection.
112
- */
113
- private resetHeartbeatTimer;
114
- /** Clear the heartbeat watchdog timer. */
115
- private clearHeartbeatTimer;
116
- }
117
- //# sourceMappingURL=sse.d.ts.map
package/dist/sse.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,2DAA2D;AAC3D,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;AAIpD,wDAAwD;AACxD,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC9C;AAID;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,kBAAkB,CAAqC;IAC/D,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,sBAAsB,CAAqC;IACnE,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,gBAAgB,CAA8C;IACtE,+EAA+E;IAC/E,OAAO,CAAC,iBAAiB,CAAU;IACnC,+DAA+D;IAC/D,OAAO,CAAC,gBAAgB,CAAS;IACjC,6DAA6D;IAC7D,OAAO,CAAC,aAAa,CAAC,CAA+B;gBAEzC,MAAM,EAAE,mBAAmB;IAMvC,mEAAmE;IACnE,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC,GAAG,IAAI;IAIxD,gEAAgE;IAChE,cAAc,CAAC,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC,GAAG,IAAI;IAI1D,kEAAkE;IAClE,gBAAgB,CAAC,OAAO,EAAE,eAAe,CAAC,UAAU,CAAC,GAAG,IAAI;IAI5D;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAItC;;;;;OAKG;IACH,OAAO,IAAI,IAAI;IAOf;;;;;OAKG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIhC;;;;;OAKG;IACH,UAAU,IAAI,IAAI;IAOlB;;;;OAIG;YACW,eAAe;IA+I7B;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IA6BrB;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAS3B,0CAA0C;IAC1C,OAAO,CAAC,mBAAmB;CAM5B"}
package/dist/sse.js DELETED
@@ -1,301 +0,0 @@
1
- // ─── SSE Client ──────────────────────────────────────────────────────────────
2
- /**
3
- * Server-Sent Events client for the Ravi real-time event stream.
4
- *
5
- * Connects to `GET /api/events/stream/` and dispatches typed events
6
- * (email_owner, email_trusted, email_untrusted) to registered handlers. Identity scoping is embedded
7
- * in the JWT token (obtained via bind-identity). Automatically reconnects
8
- * with exponential backoff on connection loss and monitors server
9
- * heartbeats to detect stale connections.
10
- *
11
- * @example
12
- * ```ts
13
- * const sse = new RaviSSEClient({
14
- * apiUrl: "https://api.ravi.dev",
15
- * token: "ey...", // bound token with identity in JWT claims
16
- * });
17
- *
18
- * sse.onEmailOwner((event) => console.log("New email:", event.subject));
19
- * sse.connect();
20
- *
21
- * // Later...
22
- * sse.disconnect();
23
- * ```
24
- */
25
- export class RaviSSEClient {
26
- apiUrl;
27
- token;
28
- controller = null;
29
- reconnectDelay = 1000;
30
- maxReconnectDelay = 30000;
31
- lastEventId = null;
32
- emailOwnerHandlers = [];
33
- emailTrustedHandlers = [];
34
- emailUntrustedHandlers = [];
35
- reconnectHandlers = [];
36
- running = false;
37
- heartbeatTimeout = null;
38
- /** Expect a keepalive or data every 60s (server sends keepalive every 30s). */
39
- heartbeatInterval = 60_000;
40
- /** Flag set when the heartbeat timer aborts the connection. */
41
- isHeartbeatAbort = false;
42
- /** Optional callback to attempt token refresh on 401/403. */
43
- onAuthFailure;
44
- constructor(config) {
45
- this.apiUrl = config.apiUrl.replace(/\/$/, "");
46
- this.token = config.token;
47
- this.onAuthFailure = config.onAuthFailure;
48
- }
49
- /** Register a handler for email events from the identity owner. */
50
- onEmailOwner(handler) {
51
- this.emailOwnerHandlers.push(handler);
52
- }
53
- /** Register a handler for email events from trusted senders. */
54
- onEmailTrusted(handler) {
55
- this.emailTrustedHandlers.push(handler);
56
- }
57
- /** Register a handler for email events from untrusted senders. */
58
- onEmailUntrusted(handler) {
59
- this.emailUntrustedHandlers.push(handler);
60
- }
61
- /**
62
- * Register a handler that fires whenever the client reconnects after a
63
- * connection drop. Useful for re-fetching state that may have been missed
64
- * during the disconnection window.
65
- */
66
- onReconnect(handler) {
67
- this.reconnectHandlers.push(handler);
68
- }
69
- /**
70
- * Open the SSE connection and begin streaming events.
71
- *
72
- * The connection loop runs in the background and will automatically
73
- * reconnect on failure. Call {@link disconnect} to stop.
74
- */
75
- connect() {
76
- this.running = true;
77
- this.startConnection().catch((err) => {
78
- console.error("[ravi] SSE connection loop terminated unexpectedly:", err);
79
- });
80
- }
81
- /**
82
- * Update the bearer token used for SSE connections.
83
- *
84
- * Takes effect on the next reconnection — the current connection
85
- * continues until it naturally drops or is aborted.
86
- */
87
- updateToken(token) {
88
- this.token = token;
89
- }
90
- /**
91
- * Gracefully close the SSE connection.
92
- *
93
- * Aborts any in-flight fetch, stops the heartbeat timer, and prevents
94
- * further reconnection attempts.
95
- */
96
- disconnect() {
97
- this.running = false;
98
- this.controller?.abort();
99
- this.controller = null;
100
- this.clearHeartbeatTimer();
101
- }
102
- /**
103
- * Core connection loop. Opens a streaming fetch to the SSE endpoint,
104
- * parses the event stream, and dispatches events. On failure, waits
105
- * with exponential backoff before retrying.
106
- */
107
- async startConnection() {
108
- let isReconnect = false;
109
- let consecutiveFailures = 0;
110
- let authRetries = 0;
111
- while (this.running) {
112
- try {
113
- this.controller = new AbortController();
114
- const headers = {
115
- Authorization: `Bearer ${this.token}`,
116
- Accept: "text/event-stream",
117
- };
118
- if (this.lastEventId) {
119
- headers["Last-Event-ID"] = this.lastEventId;
120
- }
121
- const response = await fetch(`${this.apiUrl}/api/events/stream/`, {
122
- headers,
123
- signal: this.controller.signal,
124
- });
125
- if (!response.ok) {
126
- const status = response.status;
127
- if (status === 401 || status === 403) {
128
- if (this.onAuthFailure && authRetries < 2) {
129
- authRetries++;
130
- let newToken = null;
131
- try {
132
- newToken = await this.onAuthFailure();
133
- }
134
- catch (refreshErr) {
135
- const detail = refreshErr instanceof Error ? refreshErr.message : String(refreshErr);
136
- console.error(`[ravi] SSE auth refresh callback failed: ${detail}`);
137
- }
138
- if (newToken) {
139
- this.token = newToken;
140
- continue; // retry with refreshed token
141
- }
142
- }
143
- console.error(`[ravi] SSE auth failed (${status}) — stopping`);
144
- this.running = false;
145
- return;
146
- }
147
- throw new Error(`SSE connection failed: HTTP ${status}`);
148
- }
149
- // Successful connection — reset backoff, failure counter, and auth retries
150
- this.reconnectDelay = 1000;
151
- consecutiveFailures = 0;
152
- authRetries = 0;
153
- this.resetHeartbeatTimer();
154
- // Fire reconnect handlers AFTER successful connection
155
- if (isReconnect) {
156
- for (const handler of this.reconnectHandlers) {
157
- try {
158
- handler();
159
- }
160
- catch (err) {
161
- console.error("[ravi] Reconnect handler threw:", err);
162
- }
163
- }
164
- }
165
- isReconnect = true;
166
- const reader = response.body?.getReader();
167
- if (!reader)
168
- throw new Error("No response body");
169
- const decoder = new TextDecoder();
170
- let buffer = "";
171
- // Per-event accumulators (SSE spec: fields build up until blank line)
172
- let currentId = null;
173
- let currentEvent = null;
174
- let currentData = "";
175
- while (this.running) {
176
- const { done, value } = await reader.read();
177
- if (done)
178
- break;
179
- buffer += decoder.decode(value, { stream: true });
180
- const lines = buffer.split("\n");
181
- // Keep the last incomplete line in the buffer
182
- buffer = lines.pop() ?? "";
183
- for (const rawLine of lines) {
184
- const line = rawLine.replace(/\r$/, "");
185
- if (line.startsWith(":")) {
186
- // Comment line — server keepalive
187
- this.resetHeartbeatTimer();
188
- continue;
189
- }
190
- if (line.startsWith("id:")) {
191
- currentId = line.slice(line[3] === " " ? 4 : 3).trim();
192
- }
193
- else if (line.startsWith("event:")) {
194
- currentEvent = line.slice(line[6] === " " ? 7 : 6).trim();
195
- }
196
- else if (line.startsWith("data:")) {
197
- const value = line.slice(line[5] === " " ? 6 : 5);
198
- if (currentData)
199
- currentData += "\n";
200
- currentData += value;
201
- }
202
- else if (line === "") {
203
- // Blank line = end of event dispatch
204
- this.resetHeartbeatTimer();
205
- if (currentEvent && currentData) {
206
- if (currentId)
207
- this.lastEventId = currentId;
208
- this.dispatchEvent(currentEvent, currentData);
209
- }
210
- currentId = null;
211
- currentEvent = null;
212
- currentData = "";
213
- }
214
- }
215
- }
216
- // Stream closed cleanly — clear heartbeat
217
- this.clearHeartbeatTimer();
218
- }
219
- catch (error) {
220
- this.clearHeartbeatTimer();
221
- // If disconnect() was called, exit cleanly
222
- if (!this.running)
223
- return;
224
- const errorMsg = error instanceof Error ? error.message : String(error);
225
- console.error(`[ravi] SSE connection error: ${errorMsg}`);
226
- // Heartbeat-triggered aborts are expected — don't count as failures
227
- if (this.isHeartbeatAbort) {
228
- this.isHeartbeatAbort = false;
229
- }
230
- else {
231
- consecutiveFailures++;
232
- }
233
- if (consecutiveFailures >= 50) {
234
- console.error(`[ravi] SSE giving up after ${consecutiveFailures} consecutive failures`);
235
- this.running = false;
236
- return;
237
- }
238
- // Exponential backoff
239
- await new Promise((resolve) => setTimeout(resolve, this.reconnectDelay));
240
- this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.maxReconnectDelay);
241
- isReconnect = true;
242
- }
243
- }
244
- }
245
- /**
246
- * Parse the JSON data payload and dispatch to the appropriate typed handlers.
247
- *
248
- * Logs and skips events with malformed JSON. Handler errors are caught
249
- * individually so one broken handler does not prevent others from running.
250
- */
251
- dispatchEvent(eventType, data) {
252
- let parsed;
253
- try {
254
- parsed = JSON.parse(data);
255
- }
256
- catch {
257
- console.error(`[ravi] Failed to parse SSE event (type=${eventType}): ${data.slice(0, 200)}`);
258
- return;
259
- }
260
- const handlers = eventType === "email_owner" ? this.emailOwnerHandlers
261
- : eventType === "email_trusted" ? this.emailTrustedHandlers
262
- : eventType === "email_untrusted" ? this.emailUntrustedHandlers
263
- : null;
264
- if (!handlers) {
265
- console.warn(`[ravi] Received unhandled SSE event type: ${eventType}`);
266
- return;
267
- }
268
- for (const handler of handlers) {
269
- try {
270
- handler(parsed);
271
- }
272
- catch (err) {
273
- console.error(`[ravi] SSE ${eventType} handler threw:`, err);
274
- }
275
- }
276
- }
277
- /**
278
- * Reset the heartbeat watchdog timer.
279
- *
280
- * Called whenever we receive any data from the server (keepalive comments,
281
- * event data, etc.). If no data arrives within {@link heartbeatInterval}ms,
282
- * the connection is assumed stale and the fetch is aborted to trigger
283
- * reconnection.
284
- */
285
- resetHeartbeatTimer() {
286
- this.clearHeartbeatTimer();
287
- this.heartbeatTimeout = setTimeout(() => {
288
- // No heartbeat received — force reconnect by aborting the fetch
289
- this.isHeartbeatAbort = true;
290
- this.controller?.abort();
291
- }, this.heartbeatInterval);
292
- }
293
- /** Clear the heartbeat watchdog timer. */
294
- clearHeartbeatTimer() {
295
- if (this.heartbeatTimeout) {
296
- clearTimeout(this.heartbeatTimeout);
297
- this.heartbeatTimeout = null;
298
- }
299
- }
300
- }
301
- //# sourceMappingURL=sse.js.map
package/dist/sse.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"sse.js","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"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"}