@flytedesk/app-kit 4.0.0 → 5.0.0
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/bigquery/client.d.ts +4 -4
- package/dist/bigquery/client.js +2 -2
- package/dist/bigquery/client.js.map +1 -1
- package/dist/bigquery/index.d.ts +2 -2
- package/dist/bigquery/load.d.ts +25 -7
- package/dist/bigquery/load.js +61 -31
- package/dist/bigquery/load.js.map +1 -1
- package/dist/bigquery/types.d.ts +10 -15
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type LoadRowsOptions } from "./load.js";
|
|
1
|
+
import { type LoadRowSource, type LoadRowsOptions, type LoadRowsResult } from "./load.js";
|
|
2
2
|
import type { BigQueryLike, DryRunEstimate, EstimateQueryBytesOptions, ExtractJobHandle, ExtractJobStatus, ExtractTableToGCSInput, JobLabelInput, QueryPage, RunQueryOptions, WaitForExtractJobOptions } from "./types.js";
|
|
3
3
|
export interface CreateBigQueryReadClientOptions {
|
|
4
4
|
/** Merged under any per-call `labels`/`extra` — e.g. `{app: "sms-app"}`. */
|
|
@@ -11,9 +11,9 @@ export interface BigQueryReadClient {
|
|
|
11
11
|
extractTableToGCS(input: ExtractTableToGCSInput): Promise<ExtractJobHandle>;
|
|
12
12
|
getExtractJobStatus(jobId: string): Promise<ExtractJobStatus>;
|
|
13
13
|
waitForExtractJob(jobId: string, options?: WaitForExtractJobOptions): Promise<ExtractJobStatus>;
|
|
14
|
-
/** Truncate-and-reload (or append) a table from
|
|
15
|
-
* `loadRowsWithRetry`. */
|
|
16
|
-
loadRows<T extends object>(options: LoadRowsOptions,
|
|
14
|
+
/** Truncate-and-reload (or append) a table from a stream of rows, in memory
|
|
15
|
+
* bounded by the chunk size — see `loadRowsWithRetry`. */
|
|
16
|
+
loadRows<T extends object>(options: LoadRowsOptions, source: LoadRowSource<T>): Promise<LoadRowsResult>;
|
|
17
17
|
/** Builds a `{actor, purpose, ...extra}` label set, pre-merged with this
|
|
18
18
|
* client's `defaultLabels` — pass the result as `labels` to `query`/
|
|
19
19
|
* `extractTableToGCS`. */
|
package/dist/bigquery/client.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { buildJobLabels } from "./labels.js";
|
|
10
10
|
import { extractTableToGCS, getExtractJobStatus, waitForExtractJob, } from "./extract.js";
|
|
11
|
-
import { loadRowsWithRetry } from "./load.js";
|
|
11
|
+
import { loadRowsWithRetry, } from "./load.js";
|
|
12
12
|
import { estimateQueryBytes, runQuery, runQueryAllPages } from "./query.js";
|
|
13
13
|
export function createBigQueryReadClient(bq, options = {}) {
|
|
14
14
|
const defaultLabels = options.defaultLabels ?? {};
|
|
@@ -29,7 +29,7 @@ export function createBigQueryReadClient(bq, options = {}) {
|
|
|
29
29
|
extractTableToGCS: (input) => extractTableToGCS(bq, { ...input, labels: withDefaults(input.labels) }),
|
|
30
30
|
getExtractJobStatus: (jobId) => getExtractJobStatus(bq, jobId),
|
|
31
31
|
waitForExtractJob: (jobId, waitOptions) => waitForExtractJob(bq, jobId, waitOptions),
|
|
32
|
-
loadRows: (loadOptions,
|
|
32
|
+
loadRows: (loadOptions, source) => loadRowsWithRetry(bq, { ...loadOptions, labels: withDefaults(loadOptions.labels) }, source),
|
|
33
33
|
buildJobLabels: (input) => ({
|
|
34
34
|
...defaultLabels,
|
|
35
35
|
...buildJobLabels(input),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/bigquery/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/bigquery/client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,iBAAiB,GAIlB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA+C5E,MAAM,UAAU,wBAAwB,CACtC,EAAgB,EAChB,UAA2C,EAAE;IAE7C,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IAClD,MAAM,YAAY,GAAG,CAAC,MAA+B,EAAE,EAAE,CAAC,CAAC;QACzD,GAAG,aAAa;QAChB,GAAG,MAAM;KACV,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,CAAC,YAAY,EAAE,EAAE,CACtB,QAAQ,CAAC,EAAE,EAAE;YACX,GAAG,YAAY;YACf,MAAM,EAAE,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC;SAC1C,CAAC;QACJ,aAAa,EAAE,CAAC,YAAY,EAAE,EAAE,CAC9B,gBAAgB,CAAC,EAAE,EAAE;YACnB,GAAG,YAAY;YACf,MAAM,EAAE,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC;SAC1C,CAAC;QACJ,kBAAkB,EAAE,CAAC,eAAe,EAAE,EAAE,CACtC,kBAAkB,CAAC,EAAE,EAAE,eAAe,CAAC;QACzC,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAC3B,iBAAiB,CAAC,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACzE,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,EAAE,EAAE,KAAK,CAAC;QAC9D,iBAAiB,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,CACxC,iBAAiB,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC;QAC3C,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,CAChC,iBAAiB,CACf,EAAE,EACF,EAAE,GAAG,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,EAC5D,MAAM,CACP;QACH,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC1B,GAAG,aAAa;YAChB,GAAG,cAAc,CAAC,KAAK,CAAC;SACzB,CAAC;KACH,CAAC;AACJ,CAAC"}
|
package/dist/bigquery/index.d.ts
CHANGED
|
@@ -45,8 +45,8 @@ export type { BigQueryReadClient, CreateBigQueryReadClientOptions, } from "./cli
|
|
|
45
45
|
export { runQuery, runQueryAllPages, estimateQueryBytes } from "./query.js";
|
|
46
46
|
export { extractTableToGCS, getExtractJobStatus, waitForExtractJob, } from "./extract.js";
|
|
47
47
|
export { loadRowsWithRetry } from "./load.js";
|
|
48
|
-
export type { LoadRowsOptions } from "./load.js";
|
|
48
|
+
export type { LoadRowSource, LoadRowsOptions, LoadRowsResult } from "./load.js";
|
|
49
49
|
export { buildJobLabels, sanitizeLabelValue } from "./labels.js";
|
|
50
50
|
export { unwrapBigQueryCount, unwrapBigQueryValue } from "./values.js";
|
|
51
51
|
export { BadQueryError, BigQueryReadError, DryRunBudgetExceededError, MaximumBytesBilledExceededError, PermissionDeniedError, RateLimitExceededError, classifyBigQueryError, isRetryableBigQueryError, } from "./errors.js";
|
|
52
|
-
export type { BigQueryApiErrorDetail, BigQueryCreateQueryJobOptions, BigQueryDatasetLike, BigQueryExtractOptions, BigQueryJobLike, BigQueryJobMetadata, BigQueryLike, BigQueryLoadOptions, BigQueryNextQuery, BigQueryQueryResultsOptions, BigQuerySchemaField, BigQueryTableLike, BigQueryTableReference,
|
|
52
|
+
export type { BigQueryApiErrorDetail, BigQueryCreateQueryJobOptions, BigQueryDatasetLike, BigQueryExtractOptions, BigQueryJobLike, BigQueryJobMetadata, BigQueryLike, BigQueryLoadOptions, BigQueryNextQuery, BigQueryQueryResultsOptions, BigQuerySchemaField, BigQueryTableLike, BigQueryTableReference, DryRunEstimate, EstimateQueryBytesOptions, ExtractJobHandle, ExtractJobState, ExtractJobStatus, ExtractTableToGCSInput, GcsFileLike, JobLabelInput, QueryPage, RunQueryOptions, WaitForExtractJobOptions, } from "./types.js";
|
package/dist/bigquery/load.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { BigQueryLike, BigQueryLoadOptions } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Opens the rows for one load attempt. Called once per attempt: a retry after
|
|
4
|
+
* a rate-limit error re-uploads everything, so it calls this again and must
|
|
5
|
+
* get the same rows. That is why the source is a function and not an
|
|
6
|
+
* iterable — a generator object can only be consumed once, so a retry handed
|
|
7
|
+
* the same one would silently load nothing.
|
|
8
|
+
*/
|
|
9
|
+
export type LoadRowSource<T extends object> = () => AsyncIterable<T> | Iterable<T>;
|
|
2
10
|
export interface LoadRowsOptions extends BigQueryLoadOptions {
|
|
3
11
|
datasetId: string;
|
|
4
12
|
tableId: string;
|
|
@@ -6,17 +14,27 @@ export interface LoadRowsOptions extends BigQueryLoadOptions {
|
|
|
6
14
|
attempts?: number;
|
|
7
15
|
/** Delay before the first retry; doubles every subsequent retry. Default 1000ms. */
|
|
8
16
|
initialDelayMs?: number;
|
|
17
|
+
/** Target size of each NDJSON chunk written to the load job, in bytes. The
|
|
18
|
+
* helper holds at most about one chunk being built plus what the write
|
|
19
|
+
* stream itself buffers. A single row larger than this is written as its
|
|
20
|
+
* own chunk. Default 1 MiB. */
|
|
21
|
+
chunkBytes?: number;
|
|
9
22
|
/** Injectable for tests — real code always uses a real timer. */
|
|
10
23
|
sleep?: (ms: number) => Promise<void>;
|
|
11
24
|
}
|
|
25
|
+
export interface LoadRowsResult {
|
|
26
|
+
/** Rows the successful attempt uploaded. */
|
|
27
|
+
rowCount: number;
|
|
28
|
+
}
|
|
12
29
|
/**
|
|
13
|
-
*
|
|
14
|
-
* exponential backoff ONLY when the failure is BigQuery's
|
|
30
|
+
* Streams the rows `source` yields into `datasetId.tableId` in one load job,
|
|
31
|
+
* retrying with exponential backoff ONLY when the failure is BigQuery's
|
|
15
32
|
* rateLimitExceeded/quotaExceeded class of error (see
|
|
16
|
-
* `isRetryableBigQueryError`). Any other error (bad schema, auth failure,
|
|
17
|
-
* etc.) is classified and rethrown on the first
|
|
33
|
+
* `isRetryableBigQueryError`). Any other error (bad schema, auth failure, a
|
|
34
|
+
* throw from the source, etc.) is classified and rethrown on the first
|
|
35
|
+
* attempt. Each attempt calls `source` afresh — see `LoadRowSource`.
|
|
18
36
|
*
|
|
19
|
-
* Pass `writeDisposition: "WRITE_TRUNCATE"` for a full-refresh reload
|
|
20
|
-
*
|
|
37
|
+
* Pass `writeDisposition: "WRITE_TRUNCATE"` for a full-refresh reload; omit it
|
|
38
|
+
* for an append load.
|
|
21
39
|
*/
|
|
22
|
-
export declare function loadRowsWithRetry<T extends object>(bq: BigQueryLike, options: LoadRowsOptions,
|
|
40
|
+
export declare function loadRowsWithRetry<T extends object>(bq: BigQueryLike, options: LoadRowsOptions, source: LoadRowSource<T>): Promise<LoadRowsResult>;
|
package/dist/bigquery/load.js
CHANGED
|
@@ -1,61 +1,91 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Load-job capability (AK-14 follow-on, MP-200/PLN-2):
|
|
3
|
-
* BigQuery table
|
|
2
|
+
* Load-job capability (AK-14 follow-on, MP-200/PLN-2): loads a stream of rows
|
|
3
|
+
* into a BigQuery table in one load job, with retry-with-backoff limited to
|
|
4
4
|
* BigQuery's own rate-limit/quota class of error — generalized out of
|
|
5
5
|
* media-planner's `apps/api/src/lib/bigqueryLoad.ts` (via flytedesk-id's
|
|
6
6
|
* verbatim port at `src/lib/bigqueryLoad.ts`, MP-200), which this module
|
|
7
|
-
* replaces.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* replaces.
|
|
8
|
+
*
|
|
9
|
+
* Memory is bounded by `chunkBytes`, never by the row count (AK-28): rows are
|
|
10
|
+
* pulled from the caller's source one at a time, serialized into NDJSON chunks
|
|
11
|
+
* of about `chunkBytes`, and piped into the load job's write stream with
|
|
12
|
+
* `stream.pipeline`, which stops pulling from the source whenever the write
|
|
13
|
+
* stream's buffer is full and resumes on its `drain`. A caller that reads its
|
|
14
|
+
* rows page by page (a keyset-paged or cursor read) can therefore load any
|
|
15
|
+
* number of rows in a fixed amount of memory.
|
|
10
16
|
*/
|
|
11
|
-
import {
|
|
17
|
+
import { once } from "node:events";
|
|
18
|
+
import { pipeline } from "node:stream/promises";
|
|
19
|
+
import { BigQueryReadError, classifyBigQueryError, isRetryableBigQueryError, } from "./errors.js";
|
|
12
20
|
const DEFAULT_ATTEMPTS = 5;
|
|
13
21
|
const DEFAULT_INITIAL_DELAY_MS = 1_000;
|
|
22
|
+
const DEFAULT_CHUNK_BYTES = 1024 * 1024;
|
|
14
23
|
const DEFAULT_SOURCE_FORMAT = "NEWLINE_DELIMITED_JSON";
|
|
15
24
|
function defaultSleep(ms) {
|
|
16
25
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
17
26
|
}
|
|
18
|
-
|
|
27
|
+
/** Serializes `rows` into NDJSON, one `Buffer` of about `chunkBytes` at a
|
|
28
|
+
* time, counting rows into `counter` as they are consumed. */
|
|
29
|
+
async function* ndjsonChunks(rows, chunkBytes, counter) {
|
|
30
|
+
let lines = [];
|
|
31
|
+
let size = 0;
|
|
32
|
+
for await (const row of rows) {
|
|
33
|
+
const line = `${JSON.stringify(row)}\n`;
|
|
34
|
+
lines.push(line);
|
|
35
|
+
size += Buffer.byteLength(line);
|
|
36
|
+
counter.rows += 1;
|
|
37
|
+
if (size >= chunkBytes) {
|
|
38
|
+
yield Buffer.from(lines.join(""));
|
|
39
|
+
lines = [];
|
|
40
|
+
size = 0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (lines.length > 0)
|
|
44
|
+
yield Buffer.from(lines.join(""));
|
|
45
|
+
}
|
|
46
|
+
async function runLoadJob(bq, options, source) {
|
|
19
47
|
const table = bq.dataset(options.datasetId).table(options.tableId);
|
|
20
48
|
const createWriteStream = table.createWriteStream;
|
|
21
49
|
if (!createWriteStream) {
|
|
22
50
|
throw new BigQueryReadError(`dataset(${options.datasetId}).table(${options.tableId}) does not implement createWriteStream — this BigQueryLike was not constructed for load jobs`);
|
|
23
51
|
}
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
labels: options.labels,
|
|
32
|
-
jobId: options.jobId,
|
|
33
|
-
});
|
|
34
|
-
stream.on("error", reject);
|
|
35
|
-
stream.on("complete", () => resolve());
|
|
36
|
-
for (const line of ndjson)
|
|
37
|
-
stream.write(line);
|
|
38
|
-
stream.end();
|
|
52
|
+
const stream = createWriteStream.call(table, {
|
|
53
|
+
sourceFormat: options.sourceFormat ?? DEFAULT_SOURCE_FORMAT,
|
|
54
|
+
schema: options.schema,
|
|
55
|
+
writeDisposition: options.writeDisposition,
|
|
56
|
+
createDisposition: options.createDisposition,
|
|
57
|
+
labels: options.labels,
|
|
58
|
+
jobId: options.jobId,
|
|
39
59
|
});
|
|
60
|
+
const counter = { rows: 0 };
|
|
61
|
+
// The load is done only when BigQuery reports the job "complete" AND the
|
|
62
|
+
// pipeline has flushed every chunk. `once` rejects on the stream's "error",
|
|
63
|
+
// which is how a failed job surfaces; `pipeline` rejects (and destroys the
|
|
64
|
+
// stream, aborting the upload) when the source itself throws.
|
|
65
|
+
await Promise.all([
|
|
66
|
+
once(stream, "complete"),
|
|
67
|
+
pipeline(ndjsonChunks(source(), options.chunkBytes ?? DEFAULT_CHUNK_BYTES, counter), stream),
|
|
68
|
+
]);
|
|
69
|
+
return { rowCount: counter.rows };
|
|
40
70
|
}
|
|
41
71
|
/**
|
|
42
|
-
*
|
|
43
|
-
* exponential backoff ONLY when the failure is BigQuery's
|
|
72
|
+
* Streams the rows `source` yields into `datasetId.tableId` in one load job,
|
|
73
|
+
* retrying with exponential backoff ONLY when the failure is BigQuery's
|
|
44
74
|
* rateLimitExceeded/quotaExceeded class of error (see
|
|
45
|
-
* `isRetryableBigQueryError`). Any other error (bad schema, auth failure,
|
|
46
|
-
* etc.) is classified and rethrown on the first
|
|
75
|
+
* `isRetryableBigQueryError`). Any other error (bad schema, auth failure, a
|
|
76
|
+
* throw from the source, etc.) is classified and rethrown on the first
|
|
77
|
+
* attempt. Each attempt calls `source` afresh — see `LoadRowSource`.
|
|
47
78
|
*
|
|
48
|
-
* Pass `writeDisposition: "WRITE_TRUNCATE"` for a full-refresh reload
|
|
49
|
-
*
|
|
79
|
+
* Pass `writeDisposition: "WRITE_TRUNCATE"` for a full-refresh reload; omit it
|
|
80
|
+
* for an append load.
|
|
50
81
|
*/
|
|
51
|
-
export async function loadRowsWithRetry(bq, options,
|
|
82
|
+
export async function loadRowsWithRetry(bq, options, source) {
|
|
52
83
|
const attempts = options.attempts ?? DEFAULT_ATTEMPTS;
|
|
53
84
|
const initialDelayMs = options.initialDelayMs ?? DEFAULT_INITIAL_DELAY_MS;
|
|
54
85
|
const sleep = options.sleep ?? defaultSleep;
|
|
55
86
|
for (let attempt = 1;; attempt += 1) {
|
|
56
87
|
try {
|
|
57
|
-
await runLoadJob(bq, options,
|
|
58
|
-
return;
|
|
88
|
+
return await runLoadJob(bq, options, source);
|
|
59
89
|
}
|
|
60
90
|
catch (err) {
|
|
61
91
|
if (attempt >= attempts || !isRetryableBigQueryError(err)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/bigquery/load.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/bigquery/load.ts"],"names":[],"mappings":"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"}
|
package/dist/bigquery/types.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* `@google-cloud/bigquery` calls it made; inventory-specific SQL stays behind
|
|
12
12
|
* in media-planner.
|
|
13
13
|
*/
|
|
14
|
+
import type { Writable } from "node:stream";
|
|
14
15
|
/** One structured error entry, same shape the Google APIs client library
|
|
15
16
|
* attaches to a rejected job promise's `.errors` array. */
|
|
16
17
|
export interface BigQueryApiErrorDetail {
|
|
@@ -109,15 +110,6 @@ export interface GcsFileLike {
|
|
|
109
110
|
readonly name: string;
|
|
110
111
|
};
|
|
111
112
|
}
|
|
112
|
-
/** Structural subset of Node's own Writable that `Table#createWriteStream`
|
|
113
|
-
* needs to expose — the "error"/"complete" events a load-job caller pipes
|
|
114
|
-
* rows into and waits on. */
|
|
115
|
-
export interface BigQueryWriteStreamLike {
|
|
116
|
-
on(event: "error", listener: (err: unknown) => void): this;
|
|
117
|
-
on(event: "complete", listener: () => void): this;
|
|
118
|
-
write(chunk: string): boolean;
|
|
119
|
-
end(): void;
|
|
120
|
-
}
|
|
121
113
|
/** One BigQuery table-schema field, as `createWriteStream`'s `schema` option
|
|
122
114
|
* (and the REST API's `tables.insert`) accepts it. `fields` recurses for
|
|
123
115
|
* RECORD/STRUCT columns. */
|
|
@@ -143,12 +135,15 @@ export interface BigQueryLoadOptions {
|
|
|
143
135
|
}
|
|
144
136
|
export interface BigQueryTableLike {
|
|
145
137
|
createExtractJob(destination: GcsFileLike, options?: BigQueryExtractOptions): Promise<[BigQueryJobLike, BigQueryJobMetadata]>;
|
|
146
|
-
/** Opens a load-job write stream —
|
|
147
|
-
*
|
|
148
|
-
* "
|
|
149
|
-
*
|
|
150
|
-
* `
|
|
151
|
-
|
|
138
|
+
/** Opens a load-job write stream — a real Node `Writable`, since the loader
|
|
139
|
+
* pipes NDJSON into it with `stream.pipeline` and relies on its
|
|
140
|
+
* backpressure (`write()` returning false, then "drain"). The stream emits
|
|
141
|
+
* "complete" once BigQuery finishes the job, or "error" if the job fails.
|
|
142
|
+
* Mirrors `@google-cloud/bigquery`'s `Table#createWriteStream`, which
|
|
143
|
+
* returns a `Writable`. Optional: read-only callers (query/extract) never
|
|
144
|
+
* need it — only `loadRowsWithRetry` (./load.js) does, and it fails loudly
|
|
145
|
+
* if missing. */
|
|
146
|
+
createWriteStream?(options: BigQueryLoadOptions): Writable;
|
|
152
147
|
}
|
|
153
148
|
export interface BigQueryDatasetLike {
|
|
154
149
|
table(id: string): BigQueryTableLike;
|
package/package.json
CHANGED