@miradorlabs/parallax-web 2.2.0 → 2.3.1

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/README.md CHANGED
@@ -11,6 +11,8 @@ npm install @miradorlabs/parallax-web
11
11
  ## Features
12
12
 
13
13
  - **Auto-Flush Mode** - Data automatically batches and sends after a configurable period of inactivity
14
+ - **Keep-Alive** - Automatic periodic pings to maintain trace liveness (configurable interval)
15
+ - **Trace Lifecycle** - Explicit close trace method with automatic cleanup
14
16
  - **Fluent Builder Pattern** - Method chaining for building traces
15
17
  - **Browser-optimized** - Automatic client metadata collection (browser, OS, etc.)
16
18
  - **Blockchain Integration** - Built-in support for correlating traces with blockchain transactions
@@ -75,6 +77,80 @@ trace.addEvent('transaction_signed'); // → UpdateTrace sent immediately
75
77
  trace.addTxHint('0x...', 'ethereum'); // → UpdateTrace sent immediately
76
78
  ```
77
79
 
80
+ ## Keep-Alive & Trace Lifecycle
81
+
82
+ ### Automatic Keep-Alive
83
+
84
+ The SDK automatically sends keep-alive pings to the server every 10 seconds (configurable) to maintain trace liveness. This starts automatically after the first successful trace creation.
85
+
86
+ ```typescript
87
+ // Use default 10-second interval
88
+ const client = new ParallaxClient('your-api-key');
89
+
90
+ // Or customize the interval
91
+ const client = new ParallaxClient('your-api-key', {
92
+ keepAliveIntervalMs: 15000 // Ping every 15 seconds
93
+ });
94
+
95
+ const trace = client.trace({ name: 'MyTrace' });
96
+ // Keep-alive starts automatically after first flush completes
97
+ ```
98
+
99
+ ### Closing Traces
100
+
101
+ Always close traces when you're done to clean up resources and notify the server:
102
+
103
+ ```typescript
104
+ const trace = client.trace({ name: 'UserSession' });
105
+
106
+ // ... add events, attributes, etc ...
107
+
108
+ // Close when done
109
+ await trace.close('Session ended');
110
+
111
+ // All subsequent operations are ignored
112
+ trace.addEvent('ignored'); // Logs warning, does nothing
113
+ ```
114
+
115
+ **Best Practices:**
116
+ - Always call `close()` when you're done with a trace
117
+ - Use try-catch blocks to ensure traces are closed even on errors
118
+ - Provide a meaningful reason to help with debugging
119
+
120
+ ```typescript
121
+ const trace = client.trace({ name: 'CheckoutFlow' });
122
+
123
+ try {
124
+ // ... trace user checkout flow ...
125
+ await trace.close('Checkout completed');
126
+ } catch (error) {
127
+ trace.addEvent('error', { message: error.message });
128
+ await trace.close('Checkout failed');
129
+ }
130
+ ```
131
+
132
+ ### Auto-Close on Page Unload
133
+
134
+ For browser-based applications, you can enable automatic trace closing when the user navigates away or closes the tab:
135
+
136
+ ```typescript
137
+ const trace = client.trace({
138
+ name: 'UserSession',
139
+ autoClose: true // Automatically close on page unload
140
+ });
141
+
142
+ // Trace will automatically close with reason "Page unload" when:
143
+ // - User closes the tab/window
144
+ // - User navigates to a different page
145
+ // - Page is refreshed
146
+ ```
147
+
148
+ **Important Notes:**
149
+ - Auto-close uses the `beforeunload` event
150
+ - The trace will be closed with the reason "Page unload"
151
+ - You can still manually call `close()` before page unload
152
+ - The event listener is automatically cleaned up when you manually close the trace
153
+
78
154
  ## API Reference
79
155
 
80
156
  ### ParallaxClient
@@ -96,7 +172,8 @@ new ParallaxClient(apiKey: string, options?: ParallaxClientOptions)
96
172
 
97
173
  ```typescript
98
174
  interface ParallaxClientOptions {
99
- apiUrl?: string; // Gateway URL (defaults to parallax-gateway-dev.mirador.org:443)
175
+ apiUrl?: string; // Gateway URL (defaults to parallax-gateway-dev.mirador.org:443)
176
+ keepAliveIntervalMs?: number; // Keep-alive ping interval in milliseconds (default: 10000)
100
177
  }
101
178
  ```
102
179
 
@@ -120,6 +197,7 @@ const trace = client.trace({ autoFlush: false, flushPeriodMs: 100 });
120
197
  | `includeClientMeta` | `boolean` | `true` | Include browser/OS metadata |
121
198
  | `maxRetries` | `number` | `3` | Maximum retry attempts on network failure |
122
199
  | `retryBackoff` | `number` | `1000` | Base delay in ms for exponential backoff (doubles each retry) |
200
+ | `autoClose` | `boolean` | `false` | Automatically close trace on page unload |
123
201
 
124
202
  Returns: `ParallaxTrace` builder instance
125
203
 
@@ -205,12 +283,43 @@ Get the trace ID (available after first flush completes).
205
283
  const traceId = trace.getTraceId(); // string | null
206
284
  ```
207
285
 
286
+ #### `close(reason?)`
287
+
288
+ Close the trace and stop all timers (flush timer and keep-alive timer). After calling this method, all subsequent operations will be ignored.
289
+
290
+ ```typescript
291
+ await trace.close();
292
+ await trace.close('User completed workflow');
293
+ ```
294
+
295
+ | Parameter | Type | Description |
296
+ |-----------|------|-------------|
297
+ | `reason` | `string` | Optional reason for closing the trace |
298
+
299
+ Returns: `Promise<void>`
300
+
301
+ **Important:** Once a trace is closed:
302
+ - All method calls (`addAttribute`, `addEvent`, `addTag`, `addTxHint`, `flush`) will be ignored with a warning
303
+ - The keep-alive timer will be stopped
304
+ - A close request will be sent to the server
305
+
306
+ #### `isClosed()`
307
+
308
+ Check if the trace has been closed.
309
+
310
+ ```typescript
311
+ const closed = trace.isClosed(); // boolean
312
+ ```
313
+
208
314
  ## Complete Example: Transaction Tracking
209
315
 
210
316
  ```typescript
211
317
  import { ParallaxClient } from '@miradorlabs/parallax-web';
212
318
 
213
- const client = new ParallaxClient('your-api-key');
319
+ // Create client with custom keep-alive interval (optional)
320
+ const client = new ParallaxClient('your-api-key', {
321
+ keepAliveIntervalMs: 15000 // Override default 10s interval
322
+ });
214
323
 
215
324
  async function handleWalletTransaction(userAddress: string, recipientAddress: string, amount: string) {
216
325
  const trace = client.trace({ name: 'SendETH' })
@@ -220,14 +329,23 @@ async function handleWalletTransaction(userAddress: string, recipientAddress: st
220
329
  .addTags(['transaction', 'send', 'ethereum'])
221
330
  .addEvent('wallet_connected', { wallet: 'MetaMask' });
222
331
  // → CreateTrace sent automatically
332
+ // → Keep-alive timer starts automatically
223
333
 
224
334
  trace.addEvent('user_signed');
225
335
 
226
- const receipt = await sendTransaction();
336
+ try {
337
+ const receipt = await sendTransaction();
338
+
339
+ trace.addEvent('transaction_sent', { txHash: receipt.hash })
340
+ .addTxHint(receipt.hash, 'ethereum');
341
+ // → UpdateTrace sent automatically
227
342
 
228
- trace.addEvent('transaction_sent', { txHash: receipt.hash })
229
- .addTxHint(receipt.hash, 'ethereum');
230
- // UpdateTrace sent automatically
343
+ // Close the trace when done
344
+ await trace.close('Transaction completed successfully');
345
+ } catch (error) {
346
+ trace.addEvent('transaction_failed', { error: error.message });
347
+ await trace.close('Transaction failed');
348
+ }
231
349
  }
232
350
  ```
233
351
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as mirador_gateway_parallax_web_proto_gateway_parallax_v1_parallax_gateway_pb from 'mirador-gateway-parallax-web/proto/gateway/parallax/v1/parallax_gateway_pb';
2
- import { CreateTraceRequest, CreateTraceResponse, UpdateTraceRequest, UpdateTraceResponse } from 'mirador-gateway-parallax-web/proto/gateway/parallax/v1/parallax_gateway_pb';
2
+ import { CreateTraceRequest, CreateTraceResponse, UpdateTraceRequest, UpdateTraceResponse, KeepAliveRequest, KeepAliveResponse, CloseTraceRequest, CloseTraceResponse } from 'mirador-gateway-parallax-web/proto/gateway/parallax/v1/parallax_gateway_pb';
3
3
  export { CreateTraceRequest, CreateTraceResponse } from 'mirador-gateway-parallax-web/proto/gateway/parallax/v1/parallax_gateway_pb';
4
4
 
5
5
  /**
@@ -11,6 +11,8 @@ export { CreateTraceRequest, CreateTraceResponse } from 'mirador-gateway-paralla
11
11
  interface ParallaxClientOptions {
12
12
  /** Gateway URL (defaults to parallax-gateway-dev.mirador.org:443) */
13
13
  apiUrl?: string;
14
+ /** Keep-alive ping interval in milliseconds (default: 10000) */
15
+ keepAliveIntervalMs?: number;
14
16
  }
15
17
  /**
16
18
  * Options for creating a trace
@@ -28,6 +30,8 @@ interface TraceOptions {
28
30
  maxRetries?: number;
29
31
  /** Base delay in ms for exponential backoff between retries (default: 1000) */
30
32
  retryBackoff?: number;
33
+ /** Automatically close trace on page unload (default: false) */
34
+ autoClose?: boolean;
31
35
  }
32
36
  /**
33
37
  * Supported chain names (maps to Chain enum in proto)
@@ -45,6 +49,8 @@ type ChainName = 'ethereum' | 'polygon' | 'arbitrum' | 'base' | 'optimism' | 'bs
45
49
  interface TraceSubmitter {
46
50
  _sendTrace(request: CreateTraceRequest): Promise<CreateTraceResponse>;
47
51
  _updateTrace(request: UpdateTraceRequest): Promise<UpdateTraceResponse>;
52
+ _keepAlive(request: KeepAliveRequest): Promise<KeepAliveResponse>;
53
+ _closeTrace(request: CloseTraceRequest): Promise<CloseTraceResponse>;
48
54
  }
49
55
  /** Options passed to ParallaxTrace constructor (with defaults applied) */
50
56
  interface ResolvedTraceOptions {
@@ -54,6 +60,8 @@ interface ResolvedTraceOptions {
54
60
  includeClientMeta: boolean;
55
61
  maxRetries: number;
56
62
  retryBackoff: number;
63
+ keepAliveIntervalMs: number;
64
+ autoClose: boolean;
57
65
  }
58
66
  /**
59
67
  * Builder class for constructing traces with method chaining.
@@ -67,9 +75,14 @@ declare class ParallaxTrace {
67
75
  private autoFlush;
68
76
  private flushPeriodMs;
69
77
  private flushTimer;
78
+ private keepAliveIntervalMs;
79
+ private keepAliveTimer;
80
+ private autoClose;
81
+ private unloadHandler;
70
82
  private maxRetries;
71
83
  private retryBackoff;
72
84
  private traceId;
85
+ private closed;
73
86
  private pendingAttributes;
74
87
  private pendingTags;
75
88
  private pendingEvents;
@@ -156,11 +169,34 @@ declare class ParallaxTrace {
156
169
  * Clear all pending data
157
170
  */
158
171
  private clearPending;
172
+ /**
173
+ * Start the keep-alive timer to ping the server periodically
174
+ */
175
+ private startKeepAlive;
176
+ /**
177
+ * Send a keep-alive ping to the server
178
+ */
179
+ private sendKeepAlive;
180
+ /**
181
+ * Stop the keep-alive timer
182
+ */
183
+ private stopKeepAlive;
184
+ /**
185
+ * Close the trace and stop all timers.
186
+ * After calling this method, all subsequent operations (addAttribute, addEvent, etc.) will be ignored.
187
+ * @param reason Optional reason for closing the trace
188
+ */
189
+ close(reason?: string): Promise<void>;
159
190
  /**
160
191
  * Get the trace ID (available after first flush completes)
161
192
  * @returns The trace ID or null if not yet created
162
193
  */
163
194
  getTraceId(): string | null;
195
+ /**
196
+ * Check if the trace is closed
197
+ * @returns True if the trace is closed
198
+ */
199
+ isClosed(): boolean;
164
200
  }
165
201
 
166
202
  /**
@@ -169,6 +205,7 @@ declare class ParallaxTrace {
169
205
  declare class ParallaxClient {
170
206
  apiUrl: string;
171
207
  apiKey: string;
208
+ keepAliveIntervalMs: number;
172
209
  private client;
173
210
  /**
174
211
  * Create a new ParallaxClient instance
@@ -180,6 +217,10 @@ declare class ParallaxClient {
180
217
  _sendTrace(request: CreateTraceRequest): Promise<mirador_gateway_parallax_web_proto_gateway_parallax_v1_parallax_gateway_pb.CreateTraceResponse>;
181
218
  /** @internal */
182
219
  _updateTrace(request: UpdateTraceRequest): Promise<mirador_gateway_parallax_web_proto_gateway_parallax_v1_parallax_gateway_pb.UpdateTraceResponse>;
220
+ /** @internal */
221
+ _keepAlive(request: KeepAliveRequest): Promise<mirador_gateway_parallax_web_proto_gateway_parallax_v1_parallax_gateway_pb.KeepAliveResponse>;
222
+ /** @internal */
223
+ _closeTrace(request: CloseTraceRequest): Promise<mirador_gateway_parallax_web_proto_gateway_parallax_v1_parallax_gateway_pb.CloseTraceResponse>;
183
224
  /**
184
225
  * Create a new trace builder
185
226
  *