@databricks/zerobus-ingest-sdk 1.0.0 → 1.0.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.
package/index.d.ts ADDED
@@ -0,0 +1,485 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ /**
7
+ * Record serialization format.
8
+ *
9
+ * Specifies how records should be encoded when ingested into the stream.
10
+ */
11
+ export const enum RecordType {
12
+ /** JSON encoding - records are JSON-encoded strings */
13
+ Json = 0,
14
+ /** Protocol Buffers encoding - records are binary protobuf messages */
15
+ Proto = 1
16
+ }
17
+ /**
18
+ * Configuration options for the Zerobus stream.
19
+ *
20
+ * These options control stream behavior including recovery, timeouts, and inflight limits.
21
+ */
22
+ export interface StreamConfigurationOptions {
23
+ /**
24
+ * Maximum number of unacknowledged requests that can be in flight.
25
+ * Default: 10,000
26
+ */
27
+ maxInflightRequests?: number
28
+ /**
29
+ * Enable automatic stream recovery on transient failures.
30
+ * Default: true
31
+ */
32
+ recovery?: boolean
33
+ /**
34
+ * Timeout for recovery operations in milliseconds.
35
+ * Default: 15,000 (15 seconds)
36
+ */
37
+ recoveryTimeoutMs?: number
38
+ /**
39
+ * Delay between recovery retry attempts in milliseconds.
40
+ * Default: 2,000 (2 seconds)
41
+ */
42
+ recoveryBackoffMs?: number
43
+ /**
44
+ * Maximum number of recovery attempts before giving up.
45
+ * Default: 4
46
+ */
47
+ recoveryRetries?: number
48
+ /**
49
+ * Timeout for flush operations in milliseconds.
50
+ * Default: 300,000 (5 minutes)
51
+ */
52
+ flushTimeoutMs?: number
53
+ /**
54
+ * Timeout waiting for server acknowledgments in milliseconds.
55
+ * Default: 60,000 (1 minute)
56
+ */
57
+ serverLackOfAckTimeoutMs?: number
58
+ /**
59
+ * Record serialization format.
60
+ * Use RecordType.Json for JSON encoding or RecordType.Proto for Protocol Buffers.
61
+ * Default: RecordType.Proto (Protocol Buffers)
62
+ */
63
+ recordType?: number
64
+ /**
65
+ * Maximum wait time during graceful stream close in milliseconds.
66
+ * When the server signals stream closure, this controls how long to wait
67
+ * for in-flight records to be acknowledged.
68
+ * - None (undefined): Wait for full server-specified duration
69
+ * - Some(0): Immediately trigger recovery without waiting
70
+ * - Some(x): Wait up to min(x, server_duration) milliseconds
71
+ * Default: None (wait for full server duration)
72
+ */
73
+ streamPausedMaxWaitTimeMs?: number
74
+ }
75
+ /**
76
+ * Properties of the target Delta table for ingestion.
77
+ *
78
+ * Specifies which Unity Catalog table to write to and optionally the schema descriptor
79
+ * for Protocol Buffers encoding.
80
+ */
81
+ export interface TableProperties {
82
+ /** Full table name in Unity Catalog (e.g., "catalog.schema.table") */
83
+ tableName: string
84
+ /**
85
+ * Optional Protocol Buffer descriptor as a base64-encoded string.
86
+ * If not provided, JSON encoding will be used.
87
+ */
88
+ descriptorProto?: string
89
+ }
90
+ /**
91
+ * JavaScript headers provider callback wrapper.
92
+ *
93
+ * Allows TypeScript code to provide custom authentication headers
94
+ * by implementing a getHeaders() function.
95
+ */
96
+ export interface JsHeadersProvider {
97
+ /** JavaScript function: () => Promise<Array<[string, string]>> */
98
+ getHeadersCallback: (...args: any[]) => any
99
+ }
100
+ /**
101
+ * Custom error type for Zerobus operations.
102
+ *
103
+ * This error type includes information about whether the error is retryable,
104
+ * which helps determine if automatic recovery can resolve the issue.
105
+ */
106
+ export declare class ZerobusError {
107
+ /** Returns true if this error can be automatically retried by the SDK. */
108
+ get isRetryable(): boolean
109
+ /** Get the error message. */
110
+ get message(): string
111
+ }
112
+ /**
113
+ * A stream for ingesting data into a Databricks Delta table.
114
+ *
115
+ * The stream manages a bidirectional gRPC connection, handles acknowledgments,
116
+ * and provides automatic recovery on transient failures.
117
+ *
118
+ * # Example
119
+ *
120
+ * ```typescript
121
+ * const stream = await sdk.createStream(tableProps, clientId, clientSecret, options);
122
+ * const ackPromise = await stream.ingestRecord(Buffer.from([1, 2, 3]));
123
+ * const offset = await ackPromise;
124
+ * await stream.close();
125
+ * ```
126
+ */
127
+ export declare class ZerobusStream {
128
+ /**
129
+ * Ingests a single record into the stream.
130
+ *
131
+ * **@deprecated** Use `ingestRecordOffset()` instead, which returns the offset directly
132
+ * after queuing. Then use `waitForOffset()` to wait for acknowledgment when needed.
133
+ *
134
+ * This method accepts either:
135
+ * - A Protocol Buffer encoded record as a Buffer (Vec<u8>)
136
+ * - A JSON string
137
+ *
138
+ * This method BLOCKS until the record is sent to the SDK's internal landing zone,
139
+ * then returns a Promise for the server acknowledgment. This allows you to send
140
+ * many records immediately without waiting for acknowledgments:
141
+ *
142
+ * ```typescript
143
+ * let lastAckPromise;
144
+ * for (let i = 0; i < 1000; i++) {
145
+ * // This call blocks until record is sent (in SDK)
146
+ * lastAckPromise = stream.ingestRecord(record);
147
+ * }
148
+ * // All 1000 records are now in the SDK's internal queue
149
+ * // Wait for the last acknowledgment
150
+ * await lastAckPromise;
151
+ * // Flush to ensure all records are acknowledged
152
+ * await stream.flush();
153
+ * ```
154
+ *
155
+ * # Arguments
156
+ *
157
+ * * `payload` - The record data. Accepts:
158
+ * - Buffer (low-level proto bytes)
159
+ * - string (low-level JSON string)
160
+ * - Protobuf message object with .encode() method (high-level, auto-serializes)
161
+ * - Plain JavaScript object (high-level, auto-stringifies to JSON)
162
+ *
163
+ * # Returns
164
+ *
165
+ * A Promise that resolves to the offset ID when the server acknowledges the record.
166
+ */
167
+ ingestRecord(payload: unknown): Promise<bigint>
168
+ /**
169
+ * Ingests multiple records as a single atomic batch.
170
+ *
171
+ * **@deprecated** Use `ingestRecordsOffset()` instead, which returns the offset directly
172
+ * after queuing. Then use `waitForOffset()` to wait for acknowledgment when needed.
173
+ *
174
+ * This method accepts an array of records (Protocol Buffer buffers or JSON strings)
175
+ * and ingests them as a batch. The batch receives a single acknowledgment from
176
+ * the server with all-or-nothing semantics.
177
+ *
178
+ * Similar to ingestRecord(), this BLOCKS until the batch is sent to the SDK's
179
+ * internal landing zone, then returns a Promise for the server acknowledgment.
180
+ *
181
+ * # Arguments
182
+ *
183
+ * * `records` - Array of record data (Buffer for protobuf, string for JSON)
184
+ *
185
+ * # Returns
186
+ *
187
+ * Promise resolving to:
188
+ * - `bigint`: offset ID for non-empty batches
189
+ * - `null`: for empty batches
190
+ *
191
+ * # Example
192
+ *
193
+ * ```typescript
194
+ * const buffers = records.map(r => Buffer.from(encode(r)));
195
+ * const offsetId = await stream.ingestRecords(buffers);
196
+ *
197
+ * if (offsetId !== null) {
198
+ * console.log('Batch acknowledged at offset:', offsetId);
199
+ * }
200
+ * ```
201
+ */
202
+ ingestRecords(records: Array<unknown>): Promise<bigint | null>
203
+ /**
204
+ * Ingests a single record and returns a future that resolves to the offset ID after queuing.
205
+ *
206
+ * Unlike `ingestRecord()`, this method's Promise resolves immediately after
207
+ * the record is queued, without waiting for server acknowledgment. Use
208
+ * `waitForOffset()` to wait for acknowledgment when needed.
209
+ *
210
+ * This is the recommended API for high-throughput scenarios where you want to
211
+ * decouple record ingestion from acknowledgment tracking.
212
+ *
213
+ * # Arguments
214
+ *
215
+ * * `payload` - The record data (Buffer, string, protobuf message, or plain object)
216
+ *
217
+ * # Returns
218
+ *
219
+ * `Promise<bigint>` - Resolves to the offset ID immediately after the record is queued
220
+ * (does not wait for server acknowledgment).
221
+ *
222
+ * # Example
223
+ *
224
+ * ```typescript
225
+ * // Promise resolves immediately with offset (before server ack)
226
+ * const offset1 = await stream.ingestRecordOffset(record1);
227
+ * const offset2 = await stream.ingestRecordOffset(record2);
228
+ * // Wait for both to be acknowledged
229
+ * await stream.waitForOffset(offset2);
230
+ * ```
231
+ */
232
+ ingestRecordOffset(payload: unknown): Promise<bigint>
233
+ /**
234
+ * Ingests multiple records as a batch and returns a future that resolves to the offset ID after queuing.
235
+ *
236
+ * Unlike `ingestRecords()`, this method's Promise resolves immediately after
237
+ * the batch is queued, without waiting for server acknowledgment. Use
238
+ * `waitForOffset()` to wait for acknowledgment when needed.
239
+ *
240
+ * # Arguments
241
+ *
242
+ * * `records` - Array of record data
243
+ *
244
+ * # Returns
245
+ *
246
+ * `Promise<bigint | null>` - Resolves to the offset ID immediately after the batch
247
+ * is queued (does not wait for server acknowledgment). Returns null for empty batches.
248
+ *
249
+ * # Example
250
+ *
251
+ * ```typescript
252
+ * // Promise resolves immediately with offset (before server ack)
253
+ * const offset = await stream.ingestRecordsOffset(batch);
254
+ * if (offset !== null) {
255
+ * await stream.waitForOffset(offset);
256
+ * }
257
+ * ```
258
+ */
259
+ ingestRecordsOffset(records: Array<unknown>): Promise<bigint | null>
260
+ /**
261
+ * Waits for a specific offset to be acknowledged by the server.
262
+ *
263
+ * Use this method with `ingestRecordOffset()` and `ingestRecordsOffset()` to
264
+ * selectively wait for acknowledgments. This allows you to ingest many records
265
+ * quickly and then wait only for specific offsets when needed.
266
+ *
267
+ * # Arguments
268
+ *
269
+ * * `offset_id` - The offset ID to wait for (returned by ingestRecordOffset/ingestRecordsOffset)
270
+ *
271
+ * # Errors
272
+ *
273
+ * - Timeout if acknowledgment takes too long
274
+ * - Server errors propagated immediately (no waiting for timeout)
275
+ *
276
+ * # Example
277
+ *
278
+ * ```typescript
279
+ * const offsets = [];
280
+ * for (const record of records) {
281
+ * offsets.push(await stream.ingestRecordOffset(record));
282
+ * }
283
+ * // Wait for the last offset (implies all previous are also acknowledged)
284
+ * await stream.waitForOffset(offsets[offsets.length - 1]);
285
+ * ```
286
+ */
287
+ waitForOffset(offsetId: bigint): Promise<void>
288
+ /**
289
+ * Flushes all pending records and waits for acknowledgments.
290
+ *
291
+ * This method ensures all previously ingested records have been sent to the server
292
+ * and acknowledged. It's useful for checkpointing or ensuring data durability.
293
+ *
294
+ * # Errors
295
+ *
296
+ * - Timeout errors if flush takes longer than configured timeout
297
+ * - Network errors if the connection fails during flush
298
+ */
299
+ flush(): Promise<void>
300
+ /**
301
+ * Closes the stream gracefully.
302
+ *
303
+ * This method flushes all pending records, waits for acknowledgments, and then
304
+ * closes the underlying gRPC connection. Always call this method when done with
305
+ * the stream to ensure data integrity.
306
+ *
307
+ * # Errors
308
+ *
309
+ * - Returns an error if some records could not be acknowledged
310
+ * - Network errors during the close operation
311
+ */
312
+ close(): Promise<void>
313
+ /**
314
+ * Gets the list of unacknowledged records.
315
+ *
316
+ * This method should only be called after a stream failure to retrieve records
317
+ * that were sent but not acknowledged by the server. These records can be
318
+ * re-ingested into a new stream.
319
+ *
320
+ * # Returns
321
+ *
322
+ * An array of Buffers containing the unacknowledged record payloads.
323
+ */
324
+ getUnackedRecords(): Promise<Array<Buffer>>
325
+ /**
326
+ * Gets unacknowledged records grouped by their original batches.
327
+ *
328
+ * This preserves the batch structure from ingestion:
329
+ * - Each ingestRecord() call → 1-element batch
330
+ * - Each ingestRecords() call → N-element batch
331
+ *
332
+ * Should only be called after stream failure. All records returned as Buffers
333
+ * (JSON strings are converted to UTF-8 bytes).
334
+ *
335
+ * # Returns
336
+ *
337
+ * Array of batches, where each batch is an array of Buffers
338
+ *
339
+ * # Example
340
+ *
341
+ * ```typescript
342
+ * try {
343
+ * await stream.ingestRecords(batch1);
344
+ * await stream.ingestRecords(batch2);
345
+ * } catch (error) {
346
+ * const unackedBatches = await stream.getUnackedBatches();
347
+ *
348
+ * // Re-ingest with new stream
349
+ * for (const batch of unackedBatches) {
350
+ * await newStream.ingestRecords(batch);
351
+ * }
352
+ * }
353
+ * ```
354
+ */
355
+ getUnackedBatches(): Promise<Array<Array<Buffer>>>
356
+ }
357
+ /**
358
+ * The main SDK for interacting with the Databricks Zerobus service.
359
+ *
360
+ * This is the entry point for creating ingestion streams to Delta tables.
361
+ *
362
+ * # Example
363
+ *
364
+ * ```typescript
365
+ * const sdk = new ZerobusSdk(
366
+ * "https://workspace-id.zerobus.region.cloud.databricks.com",
367
+ * "https://workspace.cloud.databricks.com"
368
+ * );
369
+ *
370
+ * const stream = await sdk.createStream(
371
+ * { tableName: "catalog.schema.table" },
372
+ * "client-id",
373
+ * "client-secret"
374
+ * );
375
+ * ```
376
+ */
377
+ export declare class ZerobusSdk {
378
+ /**
379
+ * Creates a new Zerobus SDK instance.
380
+ *
381
+ * # Arguments
382
+ *
383
+ * * `zerobus_endpoint` - The Zerobus API endpoint URL
384
+ * (e.g., "https://workspace-id.zerobus.region.cloud.databricks.com")
385
+ * * `unity_catalog_url` - The Unity Catalog endpoint URL
386
+ * (e.g., "https://workspace.cloud.databricks.com")
387
+ *
388
+ * # Errors
389
+ *
390
+ * - Invalid endpoint URLs
391
+ * - Failed to extract workspace ID from the endpoint
392
+ */
393
+ constructor(zerobusEndpoint: string, unityCatalogUrl: string)
394
+ /**
395
+ * Creates a new ingestion stream to a Delta table.
396
+ *
397
+ * This method establishes a bidirectional gRPC connection to the Zerobus service
398
+ * and prepares it for data ingestion. By default, it uses OAuth 2.0 Client Credentials
399
+ * authentication. For custom authentication (e.g., Personal Access Tokens), provide
400
+ * a custom headers_provider.
401
+ *
402
+ * # Arguments
403
+ *
404
+ * * `table_properties` - Properties of the target table including name and optional schema
405
+ * * `client_id` - OAuth 2.0 client ID (ignored if headers_provider is provided)
406
+ * * `client_secret` - OAuth 2.0 client secret (ignored if headers_provider is provided)
407
+ * * `options` - Optional stream configuration (timeouts, recovery settings, etc.)
408
+ * * `headers_provider` - Optional custom headers provider for authentication.
409
+ * If not provided, uses OAuth with client_id and client_secret.
410
+ *
411
+ * # Returns
412
+ *
413
+ * A Promise that resolves to a ZerobusStream ready for data ingestion.
414
+ *
415
+ * # Errors
416
+ *
417
+ * - Authentication failures (invalid credentials)
418
+ * - Invalid table name or insufficient permissions
419
+ * - Network connectivity issues
420
+ * - Schema validation errors
421
+ *
422
+ * # Example
423
+ *
424
+ * ```typescript
425
+ * // OAuth authentication (default)
426
+ * const stream = await sdk.createStream(
427
+ * { tableName: "catalog.schema.table" },
428
+ * "client-id",
429
+ * "client-secret"
430
+ * );
431
+ *
432
+ * // Custom authentication with headers provider
433
+ * const stream = await sdk.createStream(
434
+ * { tableName: "catalog.schema.table" },
435
+ * "", // ignored
436
+ * "", // ignored
437
+ * undefined,
438
+ * {
439
+ * getHeadersCallback: async () => [
440
+ * ["authorization", `Bearer ${myToken}`],
441
+ * ["x-databricks-zerobus-table-name", tableName]
442
+ * ]
443
+ * }
444
+ * );
445
+ * ```
446
+ */
447
+ createStream(tableProperties: TableProperties, clientId: string, clientSecret: string, options?: StreamConfigurationOptions | undefined | null, headersProvider?: JsHeadersProvider | undefined | null): Promise<ZerobusStream>
448
+ /**
449
+ * Recreates a stream with the same configuration and re-ingests unacknowledged batches.
450
+ *
451
+ * This method is the recommended approach for recovering from stream failures. It:
452
+ * 1. Retrieves all unacknowledged batches from the failed stream
453
+ * 2. Creates a new stream with identical configuration
454
+ * 3. Re-ingests all unacknowledged batches in order
455
+ * 4. Returns the new stream ready for continued ingestion
456
+ *
457
+ * # Arguments
458
+ *
459
+ * * `stream` - The failed or closed stream to recreate
460
+ *
461
+ * # Returns
462
+ *
463
+ * A Promise that resolves to a new ZerobusStream with all unacknowledged batches re-ingested.
464
+ *
465
+ * # Errors
466
+ *
467
+ * - Failed to retrieve unacknowledged batches from the original stream
468
+ * - Authentication failures when creating the new stream
469
+ * - Network connectivity issues during re-ingestion
470
+ *
471
+ * # Examples
472
+ *
473
+ * ```typescript
474
+ * try {
475
+ * await stream.ingestRecords(batch);
476
+ * } catch (error) {
477
+ * await stream.close();
478
+ * // Recreate stream with all unacked batches re-ingested
479
+ * const newStream = await sdk.recreateStream(stream);
480
+ * // Continue ingesting with newStream
481
+ * }
482
+ * ```
483
+ */
484
+ recreateStream(stream: ZerobusStream): Promise<ZerobusStream>
485
+ }