@durable-streams/server 0.1.2 → 0.1.4

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/dist/index.d.cts CHANGED
@@ -159,6 +159,15 @@ declare class StreamStore {
159
159
  private streams;
160
160
  private pendingLongPolls;
161
161
  /**
162
+ * Check if a stream is expired based on TTL or Expires-At.
163
+ */
164
+ private isExpired;
165
+ /**
166
+ * Get a stream, deleting it if expired.
167
+ * Returns undefined if stream doesn't exist or is expired.
168
+ */
169
+ private getIfNotExpired;
170
+ /**
162
171
  * Create a new stream.
163
172
  * @throws Error if stream already exists with different config
164
173
  * @returns existing stream if config matches (idempotent)
@@ -171,10 +180,11 @@ declare class StreamStore {
171
180
  }): Stream;
172
181
  /**
173
182
  * Get a stream by path.
183
+ * Returns undefined if stream doesn't exist or is expired.
174
184
  */
175
185
  get(path: string): Stream | undefined;
176
186
  /**
177
- * Check if a stream exists.
187
+ * Check if a stream exists (and is not expired).
178
188
  */
179
189
  has(path: string): boolean;
180
190
  /**
@@ -183,7 +193,7 @@ declare class StreamStore {
183
193
  delete(path: string): boolean;
184
194
  /**
185
195
  * Append data to a stream.
186
- * @throws Error if stream doesn't exist
196
+ * @throws Error if stream doesn't exist or is expired
187
197
  * @throws Error if seq is lower than lastSeq
188
198
  * @throws Error if JSON mode and array is empty
189
199
  */
@@ -193,6 +203,7 @@ declare class StreamStore {
193
203
  }): StreamMessage;
194
204
  /**
195
205
  * Read messages from a stream starting at the given offset.
206
+ * @throws Error if stream doesn't exist or is expired
196
207
  */
197
208
  read(path: string, offset?: string): {
198
209
  messages: Array<StreamMessage>;
@@ -201,10 +212,12 @@ declare class StreamStore {
201
212
  /**
202
213
  * Format messages for response.
203
214
  * For JSON mode, wraps concatenated data in array brackets.
215
+ * @throws Error if stream doesn't exist or is expired
204
216
  */
205
217
  formatResponse(path: string, messages: Array<StreamMessage>): Uint8Array;
206
218
  /**
207
219
  * Wait for new messages (long-poll).
220
+ * @throws Error if stream doesn't exist or is expired
208
221
  */
209
222
  waitForMessages(path: string, offset: string, timeoutMs: number): Promise<{
210
223
  messages: Array<StreamMessage>;
@@ -212,6 +225,7 @@ declare class StreamStore {
212
225
  }>;
213
226
  /**
214
227
  * Get the current offset for a stream.
228
+ * Returns undefined if stream doesn't exist or is expired.
215
229
  */
216
230
  getCurrentOffset(path: string): string | undefined;
217
231
  /**
@@ -263,6 +277,15 @@ declare class FileBackedStreamStore {
263
277
  */
264
278
  private streamMetaToStream;
265
279
  /**
280
+ * Check if a stream is expired based on TTL or Expires-At.
281
+ */
282
+ private isExpired;
283
+ /**
284
+ * Get stream metadata, deleting it if expired.
285
+ * Returns undefined if stream doesn't exist or is expired.
286
+ */
287
+ private getMetaIfNotExpired;
288
+ /**
266
289
  * Close the store, closing all file handles and database.
267
290
  * All data is already fsynced on each append, so no final flush needed.
268
291
  */
@@ -292,6 +315,7 @@ declare class FileBackedStreamStore {
292
315
  /**
293
316
  * Format messages for response.
294
317
  * For JSON mode, wraps concatenated data in array brackets.
318
+ * @throws Error if stream doesn't exist or is expired
295
319
  */
296
320
  formatResponse(streamPath: string, messages: Array<StreamMessage>): Uint8Array;
297
321
  getCurrentOffset(streamPath: string): string | undefined;
@@ -308,6 +332,36 @@ declare class FileBackedStreamStore {
308
332
 
309
333
  //#endregion
310
334
  //#region src/server.d.ts
335
+ /**
336
+ * HTTP server for testing durable streams.
337
+ * Supports both in-memory and file-backed storage modes.
338
+ */
339
+ /**
340
+ * Configuration for injected faults (for testing retry/resilience).
341
+ * Supports various fault types beyond simple HTTP errors.
342
+ */
343
+ interface InjectedFault {
344
+ /** HTTP status code to return (if set, returns error response) */
345
+ status?: number;
346
+ /** Number of times to trigger this fault (decremented on each use) */
347
+ count: number;
348
+ /** Optional Retry-After header value (seconds) */
349
+ retryAfter?: number;
350
+ /** Delay in milliseconds before responding */
351
+ delayMs?: number;
352
+ /** Drop the connection after sending headers (simulates network failure) */
353
+ dropConnection?: boolean;
354
+ /** Truncate response body to this many bytes */
355
+ truncateBodyBytes?: number;
356
+ /** Probability of triggering fault (0-1, default 1.0 = always) */
357
+ probability?: number;
358
+ /** Only match specific HTTP method (GET, POST, PUT, DELETE) */
359
+ method?: string;
360
+ /** Corrupt the response body by flipping random bits */
361
+ corruptBody?: boolean;
362
+ /** Add jitter to delay (random 0-jitterMs added to delayMs) */
363
+ jitterMs?: number;
364
+ }
311
365
  declare class DurableStreamTestServer {
312
366
  readonly store: StreamStore | FileBackedStreamStore;
313
367
  private server;
@@ -315,8 +369,8 @@ declare class DurableStreamTestServer {
315
369
  private _url;
316
370
  private activeSSEResponses;
317
371
  private isShuttingDown;
318
- /** Injected errors for testing retry/resilience */
319
- private injectedErrors;
372
+ /** Injected faults for testing retry/resilience */
373
+ private injectedFaults;
320
374
  constructor(options?: TestServerOptions);
321
375
  /**
322
376
  * Start the server.
@@ -337,17 +391,34 @@ declare class DurableStreamTestServer {
337
391
  /**
338
392
  * Inject an error to be returned on the next N requests to a path.
339
393
  * Used for testing retry/resilience behavior.
394
+ * @deprecated Use injectFault for full fault injection capabilities
340
395
  */
341
396
  injectError(path: string, status: number, count?: number, retryAfter?: number): void;
342
397
  /**
343
- * Clear all injected errors.
398
+ * Inject a fault to be triggered on the next N requests to a path.
399
+ * Supports various fault types: delays, connection drops, body corruption, etc.
400
+ */
401
+ injectFault(path: string, fault: Omit<InjectedFault, `count`> & {
402
+ count?: number;
403
+ }): void;
404
+ /**
405
+ * Clear all injected faults.
344
406
  */
345
- clearInjectedErrors(): void;
407
+ clearInjectedFaults(): void;
346
408
  /**
347
- * Check if there's an injected error for this path and consume it.
348
- * Returns the error config if one should be returned, null otherwise.
409
+ * Check if there's an injected fault for this path/method and consume it.
410
+ * Returns the fault config if one should be triggered, null otherwise.
349
411
  */
350
- private consumeInjectedError;
412
+ private consumeInjectedFault;
413
+ /**
414
+ * Apply delay from fault config (including jitter).
415
+ */
416
+ private applyFaultDelay;
417
+ /**
418
+ * Apply body modifications from stored fault (truncation, corruption).
419
+ * Returns modified body, or original if no modifications needed.
420
+ */
421
+ private applyFaultBodyModification;
351
422
  private handleRequest;
352
423
  /**
353
424
  * Handle PUT - create stream
@@ -380,9 +451,7 @@ declare class DurableStreamTestServer {
380
451
  */
381
452
  private handleTestInjectError;
382
453
  private readBody;
383
- }
384
-
385
- //#endregion
454
+ } //#endregion
386
455
  //#region src/path-encoding.d.ts
387
456
  /**
388
457
  * Encode a stream path to a filesystem-safe directory name using base64url encoding.
package/dist/index.d.ts CHANGED
@@ -159,6 +159,15 @@ declare class StreamStore {
159
159
  private streams;
160
160
  private pendingLongPolls;
161
161
  /**
162
+ * Check if a stream is expired based on TTL or Expires-At.
163
+ */
164
+ private isExpired;
165
+ /**
166
+ * Get a stream, deleting it if expired.
167
+ * Returns undefined if stream doesn't exist or is expired.
168
+ */
169
+ private getIfNotExpired;
170
+ /**
162
171
  * Create a new stream.
163
172
  * @throws Error if stream already exists with different config
164
173
  * @returns existing stream if config matches (idempotent)
@@ -171,10 +180,11 @@ declare class StreamStore {
171
180
  }): Stream;
172
181
  /**
173
182
  * Get a stream by path.
183
+ * Returns undefined if stream doesn't exist or is expired.
174
184
  */
175
185
  get(path: string): Stream | undefined;
176
186
  /**
177
- * Check if a stream exists.
187
+ * Check if a stream exists (and is not expired).
178
188
  */
179
189
  has(path: string): boolean;
180
190
  /**
@@ -183,7 +193,7 @@ declare class StreamStore {
183
193
  delete(path: string): boolean;
184
194
  /**
185
195
  * Append data to a stream.
186
- * @throws Error if stream doesn't exist
196
+ * @throws Error if stream doesn't exist or is expired
187
197
  * @throws Error if seq is lower than lastSeq
188
198
  * @throws Error if JSON mode and array is empty
189
199
  */
@@ -193,6 +203,7 @@ declare class StreamStore {
193
203
  }): StreamMessage;
194
204
  /**
195
205
  * Read messages from a stream starting at the given offset.
206
+ * @throws Error if stream doesn't exist or is expired
196
207
  */
197
208
  read(path: string, offset?: string): {
198
209
  messages: Array<StreamMessage>;
@@ -201,10 +212,12 @@ declare class StreamStore {
201
212
  /**
202
213
  * Format messages for response.
203
214
  * For JSON mode, wraps concatenated data in array brackets.
215
+ * @throws Error if stream doesn't exist or is expired
204
216
  */
205
217
  formatResponse(path: string, messages: Array<StreamMessage>): Uint8Array;
206
218
  /**
207
219
  * Wait for new messages (long-poll).
220
+ * @throws Error if stream doesn't exist or is expired
208
221
  */
209
222
  waitForMessages(path: string, offset: string, timeoutMs: number): Promise<{
210
223
  messages: Array<StreamMessage>;
@@ -212,6 +225,7 @@ declare class StreamStore {
212
225
  }>;
213
226
  /**
214
227
  * Get the current offset for a stream.
228
+ * Returns undefined if stream doesn't exist or is expired.
215
229
  */
216
230
  getCurrentOffset(path: string): string | undefined;
217
231
  /**
@@ -263,6 +277,15 @@ declare class FileBackedStreamStore {
263
277
  */
264
278
  private streamMetaToStream;
265
279
  /**
280
+ * Check if a stream is expired based on TTL or Expires-At.
281
+ */
282
+ private isExpired;
283
+ /**
284
+ * Get stream metadata, deleting it if expired.
285
+ * Returns undefined if stream doesn't exist or is expired.
286
+ */
287
+ private getMetaIfNotExpired;
288
+ /**
266
289
  * Close the store, closing all file handles and database.
267
290
  * All data is already fsynced on each append, so no final flush needed.
268
291
  */
@@ -292,6 +315,7 @@ declare class FileBackedStreamStore {
292
315
  /**
293
316
  * Format messages for response.
294
317
  * For JSON mode, wraps concatenated data in array brackets.
318
+ * @throws Error if stream doesn't exist or is expired
295
319
  */
296
320
  formatResponse(streamPath: string, messages: Array<StreamMessage>): Uint8Array;
297
321
  getCurrentOffset(streamPath: string): string | undefined;
@@ -308,6 +332,36 @@ declare class FileBackedStreamStore {
308
332
 
309
333
  //#endregion
310
334
  //#region src/server.d.ts
335
+ /**
336
+ * HTTP server for testing durable streams.
337
+ * Supports both in-memory and file-backed storage modes.
338
+ */
339
+ /**
340
+ * Configuration for injected faults (for testing retry/resilience).
341
+ * Supports various fault types beyond simple HTTP errors.
342
+ */
343
+ interface InjectedFault {
344
+ /** HTTP status code to return (if set, returns error response) */
345
+ status?: number;
346
+ /** Number of times to trigger this fault (decremented on each use) */
347
+ count: number;
348
+ /** Optional Retry-After header value (seconds) */
349
+ retryAfter?: number;
350
+ /** Delay in milliseconds before responding */
351
+ delayMs?: number;
352
+ /** Drop the connection after sending headers (simulates network failure) */
353
+ dropConnection?: boolean;
354
+ /** Truncate response body to this many bytes */
355
+ truncateBodyBytes?: number;
356
+ /** Probability of triggering fault (0-1, default 1.0 = always) */
357
+ probability?: number;
358
+ /** Only match specific HTTP method (GET, POST, PUT, DELETE) */
359
+ method?: string;
360
+ /** Corrupt the response body by flipping random bits */
361
+ corruptBody?: boolean;
362
+ /** Add jitter to delay (random 0-jitterMs added to delayMs) */
363
+ jitterMs?: number;
364
+ }
311
365
  declare class DurableStreamTestServer {
312
366
  readonly store: StreamStore | FileBackedStreamStore;
313
367
  private server;
@@ -315,8 +369,8 @@ declare class DurableStreamTestServer {
315
369
  private _url;
316
370
  private activeSSEResponses;
317
371
  private isShuttingDown;
318
- /** Injected errors for testing retry/resilience */
319
- private injectedErrors;
372
+ /** Injected faults for testing retry/resilience */
373
+ private injectedFaults;
320
374
  constructor(options?: TestServerOptions);
321
375
  /**
322
376
  * Start the server.
@@ -337,17 +391,34 @@ declare class DurableStreamTestServer {
337
391
  /**
338
392
  * Inject an error to be returned on the next N requests to a path.
339
393
  * Used for testing retry/resilience behavior.
394
+ * @deprecated Use injectFault for full fault injection capabilities
340
395
  */
341
396
  injectError(path: string, status: number, count?: number, retryAfter?: number): void;
342
397
  /**
343
- * Clear all injected errors.
398
+ * Inject a fault to be triggered on the next N requests to a path.
399
+ * Supports various fault types: delays, connection drops, body corruption, etc.
400
+ */
401
+ injectFault(path: string, fault: Omit<InjectedFault, `count`> & {
402
+ count?: number;
403
+ }): void;
404
+ /**
405
+ * Clear all injected faults.
344
406
  */
345
- clearInjectedErrors(): void;
407
+ clearInjectedFaults(): void;
346
408
  /**
347
- * Check if there's an injected error for this path and consume it.
348
- * Returns the error config if one should be returned, null otherwise.
409
+ * Check if there's an injected fault for this path/method and consume it.
410
+ * Returns the fault config if one should be triggered, null otherwise.
349
411
  */
350
- private consumeInjectedError;
412
+ private consumeInjectedFault;
413
+ /**
414
+ * Apply delay from fault config (including jitter).
415
+ */
416
+ private applyFaultDelay;
417
+ /**
418
+ * Apply body modifications from stored fault (truncation, corruption).
419
+ * Returns modified body, or original if no modifications needed.
420
+ */
421
+ private applyFaultBodyModification;
351
422
  private handleRequest;
352
423
  /**
353
424
  * Handle PUT - create stream
@@ -380,9 +451,7 @@ declare class DurableStreamTestServer {
380
451
  */
381
452
  private handleTestInjectError;
382
453
  private readBody;
383
- }
384
-
385
- //#endregion
454
+ } //#endregion
386
455
  //#region src/path-encoding.d.ts
387
456
  /**
388
457
  * Encode a stream path to a filesystem-safe directory name using base64url encoding.