@flytedesk/app-kit 7.1.0 → 7.2.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/README.md CHANGED
@@ -365,6 +365,14 @@ app-kit's own gate instead. Bumping the supported range means re-running that
365
365
  test against the new version and updating this section — a passing gate is
366
366
  the actual proof, not this paragraph.
367
367
 
368
+ ## Chat (`@flytedesk/app-kit/chat`)
369
+
370
+ `createDanxbotLauncher({ apiUrl, apiToken, board, profile })` dispatches chat turns
371
+ onto a danxbot board. `profile` selects one of the `top_level_agents` declared in
372
+ the consuming app's danxbot config: sms-app uses `audience-chat`, media-planner uses
373
+ `planner-chat`. The name must match a configured entry; danxbot rejects an unknown
374
+ profile with a 4xx.
375
+
368
376
  ## Tests
369
377
 
370
378
  `npm run check` is the full gate: lint, typecheck, build, unit tests, integration tests
@@ -44,8 +44,8 @@ export { createBigQueryReadClient } from "./client.js";
44
44
  export type { BigQueryReadClient, CreateBigQueryReadClientOptions, } from "./client.js";
45
45
  export { runQuery, runQueryAllPages, estimateQueryBytes } from "./query.js";
46
46
  export { extractTableToGCS, getExtractJobStatus, waitForExtractJob, } from "./extract.js";
47
- export { loadRowsWithRetry } from "./load.js";
48
- export type { LoadRowSource, LoadRowsOptions, LoadRowsResult } from "./load.js";
47
+ export { loadFileWithRetry, loadRowsWithRetry } from "./load.js";
48
+ export type { LoadJobOptions, 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, JobTimeoutError, MalformedResultSchemaError, MaximumBytesBilledExceededError, PermissionDeniedError, RateLimitExceededError, classifyBigQueryError, isRetryableBigQueryError, } from "./errors.js";
@@ -43,7 +43,7 @@
43
43
  export { createBigQueryReadClient } from "./client.js";
44
44
  export { runQuery, runQueryAllPages, estimateQueryBytes } from "./query.js";
45
45
  export { extractTableToGCS, getExtractJobStatus, waitForExtractJob, } from "./extract.js";
46
- export { loadRowsWithRetry } from "./load.js";
46
+ export { loadFileWithRetry, loadRowsWithRetry } from "./load.js";
47
47
  export { buildJobLabels, sanitizeLabelValue } from "./labels.js";
48
48
  export { unwrapBigQueryCount, unwrapBigQueryValue } from "./values.js";
49
49
  export { BadQueryError, BigQueryReadError, DryRunBudgetExceededError, JobTimeoutError, MalformedResultSchemaError, MaximumBytesBilledExceededError, PermissionDeniedError, RateLimitExceededError, classifyBigQueryError, isRetryableBigQueryError, } from "./errors.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bigquery/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAMvD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE5E,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAG9C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,EACf,0BAA0B,EAC1B,+BAA+B,EAC/B,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bigquery/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAMvD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE5E,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAQjE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,eAAe,EACf,0BAA0B,EAC1B,+BAA+B,EAC/B,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,aAAa,CAAC"}
@@ -7,20 +7,22 @@ import type { BigQueryLike, BigQueryLoadOptions } from "./types.js";
7
7
  * the same one would silently load nothing.
8
8
  */
9
9
  export type LoadRowSource<T extends object> = () => AsyncIterable<T> | Iterable<T>;
10
- export interface LoadRowsOptions extends BigQueryLoadOptions {
10
+ export interface LoadJobOptions extends BigQueryLoadOptions {
11
11
  datasetId: string;
12
12
  tableId: string;
13
13
  /** Total attempts before giving up, including the first. Default 5. */
14
14
  attempts?: number;
15
15
  /** Delay before the first retry; doubles every subsequent retry. Default 1000ms. */
16
16
  initialDelayMs?: number;
17
+ /** Injectable for tests — real code always uses a real timer. */
18
+ sleep?: (ms: number) => Promise<void>;
19
+ }
20
+ export interface LoadRowsOptions extends LoadJobOptions {
17
21
  /** Target size of each NDJSON chunk written to the load job, in bytes. The
18
22
  * helper holds at most about one chunk being built plus what the write
19
23
  * stream itself buffers. A single row larger than this is written as its
20
24
  * own chunk. Default 1 MiB. */
21
25
  chunkBytes?: number;
22
- /** Injectable for tests — real code always uses a real timer. */
23
- sleep?: (ms: number) => Promise<void>;
24
26
  }
25
27
  export interface LoadRowsResult {
26
28
  /** Rows the successful attempt uploaded. */
@@ -38,3 +40,16 @@ export interface LoadRowsResult {
38
40
  * for an append load.
39
41
  */
40
42
  export declare function loadRowsWithRetry<T extends object>(bq: BigQueryLike, options: LoadRowsOptions, source: LoadRowSource<T>): Promise<LoadRowsResult>;
43
+ /**
44
+ * Uploads the file at `path` into `datasetId.tableId` in one load job, as the
45
+ * bytes it is: already-encoded newline-delimited JSON, gzip-compressed or not
46
+ * (BigQuery reads gzip itself, and a fifth of the bytes cross the wire).
47
+ * Nothing parses a line to write it out again, which is what makes it the way
48
+ * to load a large spool. The retry, the error classes and the options are
49
+ * those of `loadRowsWithRetry`; the file is opened afresh for each attempt.
50
+ *
51
+ * `rowCount` is the rows BigQuery reports the job wrote
52
+ * (`statistics.load.outputRows`), never a count taken locally. A job that
53
+ * completes without reporting it fails the load.
54
+ */
55
+ export declare function loadFileWithRetry(bq: BigQueryLike, options: LoadJobOptions, path: string): Promise<LoadRowsResult>;
@@ -13,7 +13,12 @@
13
13
  * stream's buffer is full and resumes on its `drain`. A caller that reads its
14
14
  * rows page by page (a keyset-paged or cursor read) can therefore load any
15
15
  * number of rows in a fixed amount of memory.
16
+ *
17
+ * A caller that already holds the rows as encoded NDJSON (a spool file, gzip
18
+ * or not) loads that file as it is with `loadFileWithRetry` instead: the same
19
+ * load job, retry and error classes, with nothing parsed or re-serialised.
16
20
  */
21
+ import { createReadStream } from "node:fs";
17
22
  import { once } from "node:events";
18
23
  import { pipeline } from "node:stream/promises";
19
24
  import { BigQueryReadError, classifyBigQueryError, isRetryableBigQueryError, } from "./errors.js";
@@ -43,7 +48,7 @@ async function* ndjsonChunks(rows, chunkBytes, counter) {
43
48
  if (lines.length > 0)
44
49
  yield Buffer.from(lines.join(""));
45
50
  }
46
- async function runLoadJob(bq, options, source) {
51
+ async function runLoadJob(bq, options, openInput) {
47
52
  const table = bq.dataset(options.datasetId).table(options.tableId);
48
53
  const createWriteStream = table.createWriteStream;
49
54
  if (!createWriteStream) {
@@ -57,35 +62,38 @@ async function runLoadJob(bq, options, source) {
57
62
  labels: options.labels,
58
63
  jobId: options.jobId,
59
64
  });
60
- const counter = { rows: 0 };
65
+ const input = openInput();
61
66
  // The load is done only when BigQuery reports the job "complete" AND the
62
67
  // pipeline has flushed every chunk. `once` rejects on the stream's "error",
63
68
  // which is how a failed job surfaces; `pipeline` rejects (and destroys the
64
69
  // stream, aborting the upload) when the source itself throws.
65
- await Promise.all([
70
+ const [[job]] = (await Promise.all([
66
71
  once(stream, "complete"),
67
- pipeline(ndjsonChunks(source(), options.chunkBytes ?? DEFAULT_CHUNK_BYTES, counter), stream),
68
- ]);
69
- return { rowCount: counter.rows };
72
+ pipeline(input.chunks, stream),
73
+ ]));
74
+ return { rowCount: input.rowCount(job) };
70
75
  }
71
- /**
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
74
- * rateLimitExceeded/quotaExceeded class of error (see
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`.
78
- *
79
- * Pass `writeDisposition: "WRITE_TRUNCATE"` for a full-refresh reload; omit it
80
- * for an append load.
81
- */
82
- export async function loadRowsWithRetry(bq, options, source) {
76
+ /** The rows BigQuery reports a load job wrote; a job that does not say is a failure. */
77
+ function reportedRowCount(options, job) {
78
+ const outputRows = job?.metadata?.statistics?.load?.outputRows;
79
+ const rowCount = Number(outputRows);
80
+ if (outputRows === undefined ||
81
+ !Number.isSafeInteger(rowCount) ||
82
+ rowCount < 0) {
83
+ throw new BigQueryReadError(`${options.datasetId}.${options.tableId}: the load job did not report the rows it wrote (got ${JSON.stringify(outputRows)})`);
84
+ }
85
+ return rowCount;
86
+ }
87
+ /** Runs `openInput` as one load job, retrying with exponential backoff ONLY on
88
+ * BigQuery's rateLimitExceeded/quotaExceeded class of error. The one retry
89
+ * and error-classification path for every kind of source. */
90
+ async function loadWithRetry(bq, options, openInput) {
83
91
  const attempts = options.attempts ?? DEFAULT_ATTEMPTS;
84
92
  const initialDelayMs = options.initialDelayMs ?? DEFAULT_INITIAL_DELAY_MS;
85
93
  const sleep = options.sleep ?? defaultSleep;
86
94
  for (let attempt = 1;; attempt += 1) {
87
95
  try {
88
- return await runLoadJob(bq, options, source);
96
+ return await runLoadJob(bq, options, openInput);
89
97
  }
90
98
  catch (err) {
91
99
  if (attempt >= attempts || !isRetryableBigQueryError(err)) {
@@ -97,4 +105,42 @@ export async function loadRowsWithRetry(bq, options, source) {
97
105
  }
98
106
  }
99
107
  }
108
+ /**
109
+ * Streams the rows `source` yields into `datasetId.tableId` in one load job,
110
+ * retrying with exponential backoff ONLY when the failure is BigQuery's
111
+ * rateLimitExceeded/quotaExceeded class of error (see
112
+ * `isRetryableBigQueryError`). Any other error (bad schema, auth failure, a
113
+ * throw from the source, etc.) is classified and rethrown on the first
114
+ * attempt. Each attempt calls `source` afresh — see `LoadRowSource`.
115
+ *
116
+ * Pass `writeDisposition: "WRITE_TRUNCATE"` for a full-refresh reload; omit it
117
+ * for an append load.
118
+ */
119
+ export async function loadRowsWithRetry(bq, options, source) {
120
+ return loadWithRetry(bq, options, () => {
121
+ const counter = { rows: 0 };
122
+ return {
123
+ chunks: ndjsonChunks(source(), options.chunkBytes ?? DEFAULT_CHUNK_BYTES, counter),
124
+ rowCount: () => counter.rows,
125
+ };
126
+ });
127
+ }
128
+ /**
129
+ * Uploads the file at `path` into `datasetId.tableId` in one load job, as the
130
+ * bytes it is: already-encoded newline-delimited JSON, gzip-compressed or not
131
+ * (BigQuery reads gzip itself, and a fifth of the bytes cross the wire).
132
+ * Nothing parses a line to write it out again, which is what makes it the way
133
+ * to load a large spool. The retry, the error classes and the options are
134
+ * those of `loadRowsWithRetry`; the file is opened afresh for each attempt.
135
+ *
136
+ * `rowCount` is the rows BigQuery reports the job wrote
137
+ * (`statistics.load.outputRows`), never a count taken locally. A job that
138
+ * completes without reporting it fails the load.
139
+ */
140
+ export async function loadFileWithRetry(bq, options, path) {
141
+ return loadWithRetry(bq, options, () => ({
142
+ chunks: createReadStream(path),
143
+ rowCount: (job) => reportedRowCount(options, job),
144
+ }));
145
+ }
100
146
  //# sourceMappingURL=load.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/bigquery/load.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/bigquery/load.ts"],"names":[],"mappings":"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"}
@@ -27,7 +27,7 @@
27
27
  * apiUrl: chatEnv.danxbotApiUrl,
28
28
  * apiToken: chatEnv.danxbotApiToken,
29
29
  * board: chatEnv.danxbotBoardId,
30
- * profile: "board-chat",
30
+ * profile: "audience-chat",
31
31
  * });
32
32
  *
33
33
  * const { jobId } = await launcher.dispatchChatTurn({
@@ -27,7 +27,7 @@
27
27
  * apiUrl: chatEnv.danxbotApiUrl,
28
28
  * apiToken: chatEnv.danxbotApiToken,
29
29
  * board: chatEnv.danxbotBoardId,
30
- * profile: "board-chat",
30
+ * profile: "audience-chat",
31
31
  * });
32
32
  *
33
33
  * const { jobId } = await launcher.dispatchChatTurn({
@@ -28,9 +28,9 @@ export interface DanxbotLauncherOptions {
28
28
  apiToken: string;
29
29
  /** The danxbot board this app's chat turns dispatch onto, e.g. "sms-app:sms-app-main". */
30
30
  board: string;
31
- /** The danxbot agent profile to dispatch — the board-level chat profile the
32
- * consuming app registered (see this module's README section on wiring a
33
- * `.danxbot/config` profile override), NOT danxbot's own per-card `board-chat`. */
31
+ /** The name of a `top_level_agents` entry in the consuming app's danxbot
32
+ * config, e.g. sms-app's "audience-chat" or media-planner's "planner-chat"
33
+ * (see the README "Chat" section). */
34
34
  profile: string;
35
35
  }
36
36
  export interface DanxbotLauncher {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flytedesk/app-kit",
3
- "version": "7.1.0",
3
+ "version": "7.2.0",
4
4
  "description": "Shared platform kit for flytedesk apps: flytedesk-id auth (BFF/OIDC client) and a Postgres-native trace/audit layer.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",