@wavehouse/sdk 0.0.0-dev.h7d02b5f9a5e4 → 0.0.0-dev.h97a11a9f5a0e
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 +2 -3
- package/dist/index.cjs +73 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -2
- package/dist/index.d.ts +67 -2
- package/dist/index.js +73 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -97,9 +97,36 @@ interface TableSchema {
|
|
|
97
97
|
columns: Column[];
|
|
98
98
|
}
|
|
99
99
|
type Schemas = Record<string, TableSchema>;
|
|
100
|
+
/**
|
|
101
|
+
* A per-record outcome from a batch (array / NDJSON) insert. Mirrors the
|
|
102
|
+
* single-object response shape plus the record's position. Exactly one of
|
|
103
|
+
* `ok` / `duplicate` / `error` is set.
|
|
104
|
+
*/
|
|
105
|
+
interface InsertRecordResult {
|
|
106
|
+
/** 1-based index of the record within the submitted batch. */
|
|
107
|
+
index: number;
|
|
108
|
+
/** Set when the record was validated and published. */
|
|
109
|
+
ok?: boolean;
|
|
110
|
+
/** Set when dedup skipped the record. */
|
|
111
|
+
duplicate?: boolean;
|
|
112
|
+
/** Set (with `ok`/`duplicate` absent) when the record was rejected. */
|
|
113
|
+
error?: string;
|
|
114
|
+
}
|
|
100
115
|
interface InsertResult {
|
|
116
|
+
/** True for a fully successful insert: a single row, or a batch with no rejected records (`failed === 0`). */
|
|
101
117
|
ok: boolean;
|
|
118
|
+
/** Single insert only: set when dedup skipped the row. */
|
|
102
119
|
duplicate?: boolean;
|
|
120
|
+
/** Batch insert (array / NDJSON): number of records submitted. */
|
|
121
|
+
total?: number;
|
|
122
|
+
/** Batch insert: records validated and published. */
|
|
123
|
+
succeeded?: number;
|
|
124
|
+
/** Batch insert: records rejected — see `results`. */
|
|
125
|
+
failed?: number;
|
|
126
|
+
/** Batch insert: records skipped by dedup. */
|
|
127
|
+
duplicates?: number;
|
|
128
|
+
/** Batch insert: per-record outcomes, each `{index, ok|duplicate|error}` (may be truncated for very large batches; the counts stay authoritative). */
|
|
129
|
+
results?: InsertRecordResult[];
|
|
103
130
|
}
|
|
104
131
|
interface DLQStats {
|
|
105
132
|
tables: Record<string, number>;
|
|
@@ -396,6 +423,12 @@ declare class QueryBuilder<Row = Record<string, unknown>> implements PromiseLike
|
|
|
396
423
|
}
|
|
397
424
|
|
|
398
425
|
type CreateStreamFn<Row> = (table: string, opts?: StreamOptions) => StreamController<Row>;
|
|
426
|
+
/**
|
|
427
|
+
* Accepted sources for {@link TableRef.insertNDJSON}: a string, raw bytes, a
|
|
428
|
+
* Blob/File (browser file inputs), or a byte stream. Non-string sources are
|
|
429
|
+
* read fully before sending.
|
|
430
|
+
*/
|
|
431
|
+
type NDJSONSource = string | Uint8Array | Blob | ReadableStream<Uint8Array>;
|
|
399
432
|
/**
|
|
400
433
|
* Reference to a table. NOT thenable — safe to pass around without triggering requests.
|
|
401
434
|
* Use `.fetch()`, `.select()`, `.insert()`, `.schema()`, or `.stream()` to act on it.
|
|
@@ -409,10 +442,42 @@ declare class TableRef<Row = Record<string, unknown>> {
|
|
|
409
442
|
fetch(opts?: FetchOptions): Promise<Result<Row[]>>;
|
|
410
443
|
/** Start building a typed query. Returns an immutable, PromiseLike QueryBuilder. */
|
|
411
444
|
select(...columns: string[]): QueryBuilder<Row>;
|
|
412
|
-
/**
|
|
445
|
+
/**
|
|
446
|
+
* Insert one or more rows into this table.
|
|
447
|
+
*
|
|
448
|
+
* A single object is sent as a JSON `POST /v1/ingest`. An **array** is
|
|
449
|
+
* serialized to NDJSON (one record per line) and sent as a single
|
|
450
|
+
* `application/x-ndjson` request: a bad record no longer fails or hides the
|
|
451
|
+
* rest of the batch — per-record outcomes come back in the result
|
|
452
|
+
* (`failed` / `results`), and `ok` is true only when every record succeeded.
|
|
453
|
+
*
|
|
454
|
+
* The array path sends one request regardless of size; bounded-concurrency
|
|
455
|
+
* chunking of very large arrays is tracked separately (#196). For NDJSON you
|
|
456
|
+
* already have (a file or stream), use {@link insertNDJSON}.
|
|
457
|
+
*/
|
|
413
458
|
insert(data: Partial<Row> | Partial<Row>[], opts?: {
|
|
414
459
|
signal?: AbortSignal;
|
|
415
460
|
}): Promise<Result<InsertResult>>;
|
|
461
|
+
/**
|
|
462
|
+
* Insert pre-formatted NDJSON (newline-delimited JSON, one record per line)
|
|
463
|
+
* from a string, raw bytes, a Blob/File, or a byte stream — e.g. a `.ndjson`
|
|
464
|
+
* file or a stream produced by another system. For in-memory rows, prefer
|
|
465
|
+
* {@link insert}.
|
|
466
|
+
*
|
|
467
|
+
* Non-string sources are read fully into memory before sending (the server
|
|
468
|
+
* streams the parse). Returns the same per-record batch summary as an array
|
|
469
|
+
* `insert`.
|
|
470
|
+
*/
|
|
471
|
+
insertNDJSON(source: NDJSONSource, opts?: {
|
|
472
|
+
signal?: AbortSignal;
|
|
473
|
+
}): Promise<Result<InsertResult>>;
|
|
474
|
+
/**
|
|
475
|
+
* @internal Send an NDJSON body and map the server's batch response onto an
|
|
476
|
+
* {@link InsertResult}. A transport / whole-request failure surfaces as the
|
|
477
|
+
* Result error arm; a processed batch (even with rejected records) surfaces
|
|
478
|
+
* as the success arm with `ok = failed === 0`.
|
|
479
|
+
*/
|
|
480
|
+
private _sendNDJSON;
|
|
416
481
|
/** Fetch the schema for this table. */
|
|
417
482
|
schema(opts?: {
|
|
418
483
|
signal?: AbortSignal;
|
|
@@ -458,4 +523,4 @@ declare class WaveHouseClient<DB extends Database = Database> {
|
|
|
458
523
|
/** Create a new WaveHouse client instance. */
|
|
459
524
|
declare function createClient<DB extends Database = Database>(config: ClientConfig<DB>): WaveHouseClient<DB>;
|
|
460
525
|
|
|
461
|
-
export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchOptions, type FilterOp, type InsertResult, LiveQuery, type OrderClause, type ParamDef, type Pipe, PipeRef, PipesNamespace, type Policy, type PolicyFilter, PolicyNamespace, QueryBuilder, type QueryFilter, type Result, type RolePermissions, SchemaNamespace, type Schemas, StreamController, type StreamEvent, type StreamOptions, type StreamStatus, type StreamSubscriber, type StructuredQuery, SysNamespace, type TablePolicy, TableRef, type TableSchema, type TimeRange, type ValidationResult, WaveHouseClient, type WaveHouseError, createClient };
|
|
526
|
+
export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchOptions, type FilterOp, type InsertRecordResult, type InsertResult, LiveQuery, type NDJSONSource, type OrderClause, type ParamDef, type Pipe, PipeRef, PipesNamespace, type Policy, type PolicyFilter, PolicyNamespace, QueryBuilder, type QueryFilter, type Result, type RolePermissions, SchemaNamespace, type Schemas, StreamController, type StreamEvent, type StreamOptions, type StreamStatus, type StreamSubscriber, type StructuredQuery, SysNamespace, type TablePolicy, TableRef, type TableSchema, type TimeRange, type ValidationResult, WaveHouseClient, type WaveHouseError, createClient };
|
package/dist/index.d.ts
CHANGED
|
@@ -97,9 +97,36 @@ interface TableSchema {
|
|
|
97
97
|
columns: Column[];
|
|
98
98
|
}
|
|
99
99
|
type Schemas = Record<string, TableSchema>;
|
|
100
|
+
/**
|
|
101
|
+
* A per-record outcome from a batch (array / NDJSON) insert. Mirrors the
|
|
102
|
+
* single-object response shape plus the record's position. Exactly one of
|
|
103
|
+
* `ok` / `duplicate` / `error` is set.
|
|
104
|
+
*/
|
|
105
|
+
interface InsertRecordResult {
|
|
106
|
+
/** 1-based index of the record within the submitted batch. */
|
|
107
|
+
index: number;
|
|
108
|
+
/** Set when the record was validated and published. */
|
|
109
|
+
ok?: boolean;
|
|
110
|
+
/** Set when dedup skipped the record. */
|
|
111
|
+
duplicate?: boolean;
|
|
112
|
+
/** Set (with `ok`/`duplicate` absent) when the record was rejected. */
|
|
113
|
+
error?: string;
|
|
114
|
+
}
|
|
100
115
|
interface InsertResult {
|
|
116
|
+
/** True for a fully successful insert: a single row, or a batch with no rejected records (`failed === 0`). */
|
|
101
117
|
ok: boolean;
|
|
118
|
+
/** Single insert only: set when dedup skipped the row. */
|
|
102
119
|
duplicate?: boolean;
|
|
120
|
+
/** Batch insert (array / NDJSON): number of records submitted. */
|
|
121
|
+
total?: number;
|
|
122
|
+
/** Batch insert: records validated and published. */
|
|
123
|
+
succeeded?: number;
|
|
124
|
+
/** Batch insert: records rejected — see `results`. */
|
|
125
|
+
failed?: number;
|
|
126
|
+
/** Batch insert: records skipped by dedup. */
|
|
127
|
+
duplicates?: number;
|
|
128
|
+
/** Batch insert: per-record outcomes, each `{index, ok|duplicate|error}` (may be truncated for very large batches; the counts stay authoritative). */
|
|
129
|
+
results?: InsertRecordResult[];
|
|
103
130
|
}
|
|
104
131
|
interface DLQStats {
|
|
105
132
|
tables: Record<string, number>;
|
|
@@ -396,6 +423,12 @@ declare class QueryBuilder<Row = Record<string, unknown>> implements PromiseLike
|
|
|
396
423
|
}
|
|
397
424
|
|
|
398
425
|
type CreateStreamFn<Row> = (table: string, opts?: StreamOptions) => StreamController<Row>;
|
|
426
|
+
/**
|
|
427
|
+
* Accepted sources for {@link TableRef.insertNDJSON}: a string, raw bytes, a
|
|
428
|
+
* Blob/File (browser file inputs), or a byte stream. Non-string sources are
|
|
429
|
+
* read fully before sending.
|
|
430
|
+
*/
|
|
431
|
+
type NDJSONSource = string | Uint8Array | Blob | ReadableStream<Uint8Array>;
|
|
399
432
|
/**
|
|
400
433
|
* Reference to a table. NOT thenable — safe to pass around without triggering requests.
|
|
401
434
|
* Use `.fetch()`, `.select()`, `.insert()`, `.schema()`, or `.stream()` to act on it.
|
|
@@ -409,10 +442,42 @@ declare class TableRef<Row = Record<string, unknown>> {
|
|
|
409
442
|
fetch(opts?: FetchOptions): Promise<Result<Row[]>>;
|
|
410
443
|
/** Start building a typed query. Returns an immutable, PromiseLike QueryBuilder. */
|
|
411
444
|
select(...columns: string[]): QueryBuilder<Row>;
|
|
412
|
-
/**
|
|
445
|
+
/**
|
|
446
|
+
* Insert one or more rows into this table.
|
|
447
|
+
*
|
|
448
|
+
* A single object is sent as a JSON `POST /v1/ingest`. An **array** is
|
|
449
|
+
* serialized to NDJSON (one record per line) and sent as a single
|
|
450
|
+
* `application/x-ndjson` request: a bad record no longer fails or hides the
|
|
451
|
+
* rest of the batch — per-record outcomes come back in the result
|
|
452
|
+
* (`failed` / `results`), and `ok` is true only when every record succeeded.
|
|
453
|
+
*
|
|
454
|
+
* The array path sends one request regardless of size; bounded-concurrency
|
|
455
|
+
* chunking of very large arrays is tracked separately (#196). For NDJSON you
|
|
456
|
+
* already have (a file or stream), use {@link insertNDJSON}.
|
|
457
|
+
*/
|
|
413
458
|
insert(data: Partial<Row> | Partial<Row>[], opts?: {
|
|
414
459
|
signal?: AbortSignal;
|
|
415
460
|
}): Promise<Result<InsertResult>>;
|
|
461
|
+
/**
|
|
462
|
+
* Insert pre-formatted NDJSON (newline-delimited JSON, one record per line)
|
|
463
|
+
* from a string, raw bytes, a Blob/File, or a byte stream — e.g. a `.ndjson`
|
|
464
|
+
* file or a stream produced by another system. For in-memory rows, prefer
|
|
465
|
+
* {@link insert}.
|
|
466
|
+
*
|
|
467
|
+
* Non-string sources are read fully into memory before sending (the server
|
|
468
|
+
* streams the parse). Returns the same per-record batch summary as an array
|
|
469
|
+
* `insert`.
|
|
470
|
+
*/
|
|
471
|
+
insertNDJSON(source: NDJSONSource, opts?: {
|
|
472
|
+
signal?: AbortSignal;
|
|
473
|
+
}): Promise<Result<InsertResult>>;
|
|
474
|
+
/**
|
|
475
|
+
* @internal Send an NDJSON body and map the server's batch response onto an
|
|
476
|
+
* {@link InsertResult}. A transport / whole-request failure surfaces as the
|
|
477
|
+
* Result error arm; a processed batch (even with rejected records) surfaces
|
|
478
|
+
* as the success arm with `ok = failed === 0`.
|
|
479
|
+
*/
|
|
480
|
+
private _sendNDJSON;
|
|
416
481
|
/** Fetch the schema for this table. */
|
|
417
482
|
schema(opts?: {
|
|
418
483
|
signal?: AbortSignal;
|
|
@@ -458,4 +523,4 @@ declare class WaveHouseClient<DB extends Database = Database> {
|
|
|
458
523
|
/** Create a new WaveHouse client instance. */
|
|
459
524
|
declare function createClient<DB extends Database = Database>(config: ClientConfig<DB>): WaveHouseClient<DB>;
|
|
460
525
|
|
|
461
|
-
export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchOptions, type FilterOp, type InsertResult, LiveQuery, type OrderClause, type ParamDef, type Pipe, PipeRef, PipesNamespace, type Policy, type PolicyFilter, PolicyNamespace, QueryBuilder, type QueryFilter, type Result, type RolePermissions, SchemaNamespace, type Schemas, StreamController, type StreamEvent, type StreamOptions, type StreamStatus, type StreamSubscriber, type StructuredQuery, SysNamespace, type TablePolicy, TableRef, type TableSchema, type TimeRange, type ValidationResult, WaveHouseClient, type WaveHouseError, createClient };
|
|
526
|
+
export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchOptions, type FilterOp, type InsertRecordResult, type InsertResult, LiveQuery, type NDJSONSource, type OrderClause, type ParamDef, type Pipe, PipeRef, PipesNamespace, type Policy, type PolicyFilter, PolicyNamespace, QueryBuilder, type QueryFilter, type Result, type RolePermissions, SchemaNamespace, type Schemas, StreamController, type StreamEvent, type StreamOptions, type StreamStatus, type StreamSubscriber, type StructuredQuery, SysNamespace, type TablePolicy, TableRef, type TableSchema, type TimeRange, type ValidationResult, WaveHouseClient, type WaveHouseError, createClient };
|
package/dist/index.js
CHANGED
|
@@ -39,9 +39,10 @@ function err(error) {
|
|
|
39
39
|
async function request(ctx, opts) {
|
|
40
40
|
const url = buildURL(ctx.baseURL, opts.path, opts.params);
|
|
41
41
|
const headers = {
|
|
42
|
-
"Content-Type": "application/json",
|
|
42
|
+
"Content-Type": opts.contentType ?? "application/json",
|
|
43
43
|
Accept: "application/json"
|
|
44
44
|
};
|
|
45
|
+
const requestBody = opts.rawBody !== void 0 ? opts.rawBody : opts.body !== void 0 ? JSON.stringify(opts.body) : void 0;
|
|
45
46
|
if (ctx.auth) {
|
|
46
47
|
const token = await ctx.auth();
|
|
47
48
|
if (token) {
|
|
@@ -55,7 +56,7 @@ async function request(ctx, opts) {
|
|
|
55
56
|
const res = await fetch(url, {
|
|
56
57
|
method: opts.method,
|
|
57
58
|
headers,
|
|
58
|
-
body:
|
|
59
|
+
body: requestBody,
|
|
59
60
|
signal: opts.signal
|
|
60
61
|
});
|
|
61
62
|
if (res.ok) {
|
|
@@ -745,11 +746,11 @@ var QueryBuilder = class _QueryBuilder {
|
|
|
745
746
|
if (error) return err(error);
|
|
746
747
|
const rows = data;
|
|
747
748
|
const hasMore = effectiveLimit != null && rows.length >= effectiveLimit;
|
|
748
|
-
if (hasMore) {
|
|
749
|
+
if (hasMore && this._state.orderBy.length > 0) {
|
|
749
750
|
const nextFn = () => this._fetchNext(rows, effectiveLimit, opts);
|
|
750
751
|
return okPage(rows, true, nextFn);
|
|
751
752
|
}
|
|
752
|
-
return okPage(rows,
|
|
753
|
+
return okPage(rows, hasMore);
|
|
753
754
|
}
|
|
754
755
|
stream(opts) {
|
|
755
756
|
const raw = this._createStream(this._state.table, opts);
|
|
@@ -792,27 +793,23 @@ var QueryBuilder = class _QueryBuilder {
|
|
|
792
793
|
if (this._state.aggregations.length > 0) ast.aggregations = this._state.aggregations;
|
|
793
794
|
if (this._state.filters.length > 0) ast.filters = this._state.filters;
|
|
794
795
|
if (this._state.groupBy.length > 0) ast.group_by = this._state.groupBy;
|
|
795
|
-
if (this._state.orderBy.length > 0)
|
|
796
|
-
ast.order_by = this._state.orderBy;
|
|
797
|
-
} else if (effectiveLimit != null && this._state.aggregations.length === 0) {
|
|
798
|
-
ast.order_by = [{ column: "received_timestamp", dir: "desc" }];
|
|
799
|
-
}
|
|
796
|
+
if (this._state.orderBy.length > 0) ast.order_by = this._state.orderBy;
|
|
800
797
|
if (effectiveLimit != null) ast.limit = effectiveLimit;
|
|
801
798
|
if (this._state.timeRange) ast.time_range = this._state.timeRange;
|
|
802
799
|
return ast;
|
|
803
800
|
}
|
|
804
801
|
async _fetchNext(prevRows, _limit, opts) {
|
|
805
|
-
const
|
|
806
|
-
|
|
802
|
+
const cursor = this._state.orderBy[0];
|
|
803
|
+
if (cursor == null) return okPage([], false);
|
|
804
|
+
const { column: orderCol, dir: orderDir } = cursor;
|
|
807
805
|
const lastRow = prevRows[prevRows.length - 1];
|
|
808
806
|
const lastValue = lastRow?.[orderCol];
|
|
809
807
|
if (lastValue === void 0) return okPage([], false);
|
|
810
808
|
const cursorOp = orderDir === "desc" ? "lt" : "gt";
|
|
811
809
|
const cursorFilter = { column: orderCol, op: cursorOp, value: lastValue };
|
|
812
|
-
const orderBy = this._state.orderBy.length > 0 ? this._state.orderBy : [{ column: orderCol, dir: orderDir }];
|
|
813
810
|
const nextBuilder = this._clone({
|
|
814
811
|
filters: [...this._state.filters, cursorFilter],
|
|
815
|
-
orderBy
|
|
812
|
+
orderBy: this._state.orderBy
|
|
816
813
|
});
|
|
817
814
|
return nextBuilder.fetch(opts);
|
|
818
815
|
}
|
|
@@ -903,6 +900,12 @@ function projectColumns(row, columns) {
|
|
|
903
900
|
}
|
|
904
901
|
|
|
905
902
|
// src/table.ts
|
|
903
|
+
var NDJSON_CONTENT_TYPE = "application/x-ndjson";
|
|
904
|
+
async function ndjsonSourceToString(source) {
|
|
905
|
+
if (typeof source === "string") return source;
|
|
906
|
+
if (source instanceof Uint8Array) return new TextDecoder().decode(source);
|
|
907
|
+
return new Response(source).text();
|
|
908
|
+
}
|
|
906
909
|
var TableRef = class {
|
|
907
910
|
_ctx;
|
|
908
911
|
_table;
|
|
@@ -931,22 +934,26 @@ var TableRef = class {
|
|
|
931
934
|
this._createStream
|
|
932
935
|
);
|
|
933
936
|
}
|
|
934
|
-
/**
|
|
937
|
+
/**
|
|
938
|
+
* Insert one or more rows into this table.
|
|
939
|
+
*
|
|
940
|
+
* A single object is sent as a JSON `POST /v1/ingest`. An **array** is
|
|
941
|
+
* serialized to NDJSON (one record per line) and sent as a single
|
|
942
|
+
* `application/x-ndjson` request: a bad record no longer fails or hides the
|
|
943
|
+
* rest of the batch — per-record outcomes come back in the result
|
|
944
|
+
* (`failed` / `results`), and `ok` is true only when every record succeeded.
|
|
945
|
+
*
|
|
946
|
+
* The array path sends one request regardless of size; bounded-concurrency
|
|
947
|
+
* chunking of very large arrays is tracked separately (#196). For NDJSON you
|
|
948
|
+
* already have (a file or stream), use {@link insertNDJSON}.
|
|
949
|
+
*/
|
|
935
950
|
async insert(data, opts) {
|
|
936
951
|
if (Array.isArray(data)) {
|
|
937
|
-
|
|
938
|
-
(
|
|
939
|
-
method: "POST",
|
|
940
|
-
path: `/v1/ingest?table=${encodeURIComponent(this._table)}`,
|
|
941
|
-
body: row,
|
|
942
|
-
signal: opts?.signal
|
|
943
|
-
})
|
|
944
|
-
);
|
|
945
|
-
const results = await Promise.all(promises);
|
|
946
|
-
for (const res2 of results) {
|
|
947
|
-
if (res2.error) return err(res2.error);
|
|
952
|
+
if (data.length === 0) {
|
|
953
|
+
return ok({ ok: true, total: 0, succeeded: 0, failed: 0, duplicates: 0, results: [] });
|
|
948
954
|
}
|
|
949
|
-
|
|
955
|
+
const ndjson = data.map((row) => JSON.stringify(row)).join("\n");
|
|
956
|
+
return this._sendNDJSON(ndjson, opts);
|
|
950
957
|
}
|
|
951
958
|
const { data: res, error } = await request(this._ctx, {
|
|
952
959
|
method: "POST",
|
|
@@ -959,6 +966,46 @@ var TableRef = class {
|
|
|
959
966
|
if (res?.duplicate != null) result.duplicate = res.duplicate;
|
|
960
967
|
return ok(result);
|
|
961
968
|
}
|
|
969
|
+
/**
|
|
970
|
+
* Insert pre-formatted NDJSON (newline-delimited JSON, one record per line)
|
|
971
|
+
* from a string, raw bytes, a Blob/File, or a byte stream — e.g. a `.ndjson`
|
|
972
|
+
* file or a stream produced by another system. For in-memory rows, prefer
|
|
973
|
+
* {@link insert}.
|
|
974
|
+
*
|
|
975
|
+
* Non-string sources are read fully into memory before sending (the server
|
|
976
|
+
* streams the parse). Returns the same per-record batch summary as an array
|
|
977
|
+
* `insert`.
|
|
978
|
+
*/
|
|
979
|
+
async insertNDJSON(source, opts) {
|
|
980
|
+
const ndjson = await ndjsonSourceToString(source);
|
|
981
|
+
return this._sendNDJSON(ndjson, opts);
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* @internal Send an NDJSON body and map the server's batch response onto an
|
|
985
|
+
* {@link InsertResult}. A transport / whole-request failure surfaces as the
|
|
986
|
+
* Result error arm; a processed batch (even with rejected records) surfaces
|
|
987
|
+
* as the success arm with `ok = failed === 0`.
|
|
988
|
+
*/
|
|
989
|
+
async _sendNDJSON(ndjson, opts) {
|
|
990
|
+
const { data, error } = await request(this._ctx, {
|
|
991
|
+
method: "POST",
|
|
992
|
+
path: `/v1/ingest?table=${encodeURIComponent(this._table)}`,
|
|
993
|
+
rawBody: ndjson,
|
|
994
|
+
contentType: NDJSON_CONTENT_TYPE,
|
|
995
|
+
signal: opts?.signal
|
|
996
|
+
});
|
|
997
|
+
if (error) return err(error);
|
|
998
|
+
const r = data ?? { total: 0, succeeded: 0, failed: 0, duplicates: 0 };
|
|
999
|
+
const result = {
|
|
1000
|
+
ok: r.failed === 0,
|
|
1001
|
+
total: r.total,
|
|
1002
|
+
succeeded: r.succeeded,
|
|
1003
|
+
failed: r.failed,
|
|
1004
|
+
duplicates: r.duplicates
|
|
1005
|
+
};
|
|
1006
|
+
if (r.results && r.results.length > 0) result.results = r.results;
|
|
1007
|
+
return ok(result);
|
|
1008
|
+
}
|
|
962
1009
|
/** Fetch the schema for this table. */
|
|
963
1010
|
async schema(opts) {
|
|
964
1011
|
const { data, error } = await request(this._ctx, {
|