[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81592":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":12,"openIssues":13,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":13,"stars7d":13,"stars30d":13,"stars90d":13,"forks30d":13,"starsTrendScore":13,"compositeScore":13,"rankGlobal":10,"rankLanguage":10,"license":14,"archived":15,"fork":15,"defaultBranch":16,"hasWiki":15,"hasPages":15,"topics":17,"createdAt":10,"pushedAt":10,"updatedAt":21,"readmeContent":22,"aiSummary":23,"trendingCount":13,"starSnapshotCount":13,"syncStatus":24,"lastSyncTime":25,"discoverSource":26},81592,"quack-protocol","tobilg\u002Fquack-protocol","tobilg","A TypeScript client library for the Quack protocol","https:\u002F\u002Fquack-protocol-sdk.gh.tobilg.com",null,"TypeScript",23,0,"MIT License",false,"main",[18,19,20],"duckdb","quack","typescript","2026-06-12 02:04:17","# @quack-protocol\u002Fsdk\n\nTypeScript client and binary codecs for DuckDB's experimental Quack protocol.\n\nThis package implements the Quack HTTP transport, DuckDB `BinarySerializer`\nfield\u002Fobject encoding, logical type metadata, `DataChunk` decoding, and flat\n`DataChunk` encoding for append workloads. It is ESM-only, has no runtime\ndependencies, and uses the standard `fetch` API, so it can run in modern\nbrowsers, Node, and other runtimes with a compatible fetch implementation.\n\nQuack is still experimental upstream. The protocol is tightly coupled to\nDuckDB's internal binary serialization format. The implementation here targets\nthe wire format documented in\n[Quack protocol analysis](https:\u002F\u002Fgist.github.com\u002Ftobilg\u002F9ced9d08f6141b723f26cf205d5b9ece).\n\n## Status\n\nImplemented:\n\n- Connection string parsing for bare hosts like `localhost:9494`, DuckDB-style\n  Quack URIs like `quack:host:port`, bracketed IPv6 hosts, and direct\n  `http:\u002F\u002F` or `https:\u002F\u002F` URLs.\n- HTTP `POST \u002Fquack` transport with `application\u002Fduckdb` request and response\n  bodies.\n- Connection, prepare\u002Fquery, fetch, append, disconnect, success, and error\n  messages.\n- Typed query rows, row streaming, `first()`, `one()`, `values()`, scoped\n  connections, transactions, request cancellation, and request timeouts.\n- SQL parameter formatting for positional `?` and named `:name` placeholders.\n- DuckDB binary object fields, required\u002Fdefault properties, nullable pointers,\n  lists, strings, blobs, signed\u002Funsigned LEB128 integers, and signed\u002Funsigned\n  hugeints.\n- Logical type metadata for the scalar, decimal, enum, list, struct, map,\n  array, aggregate-state, template, generic, string, any, unbound legacy, and\n  geometry CRS paths needed for supported Quack traffic.\n- Result `DataChunk` decoding for flat, constant, dictionary, and sequence\n  vectors.\n- Flat append chunk encoding for scalars, decimals, UUIDs, enums, temporal\n  values, intervals, strings, blobs, lists\u002Fmaps, structs, and arrays.\n- Row-oriented append helpers for common application code, plus low-level\n  protocol exports under `@quack-protocol\u002Fsdk\u002Fprotocol`.\n\n## Installation\n\n```sh\nnpm install @quack-protocol\u002Fsdk\n```\n\nFor local development from this repository:\n\n```sh\nnpm install\nnpm run build\n```\n\n## Connecting\n\n```ts\nimport { QuackClient } from \"@quack-protocol\u002Fsdk\";\n\nconst client = await QuackClient.connect(\"localhost:9494\", {\n  authToken: \"super_secret\"\n});\n\ntry {\n  const result = await client.query(\"SELECT 42 AS answer\");\n  console.log(result.rows());\n} finally {\n  await client.disconnect();\n}\n```\n\n`QuackClient.connect()` accepts:\n\n- `authToken`: token sent in the connection request.\n- `clientDuckdbVersion`: optional client DuckDB version metadata.\n- `clientPlatform`: optional platform string; defaults to the runtime user\n  agent or `quack-ts`.\n- `minSupportedQuackVersion` and `maxSupportedQuackVersion`: protocol version\n  range, defaulting to version `1`.\n- `fetch`: custom fetch implementation.\n- `headers`: additional HTTP headers.\n- `ssl`: force non-HTTP connection strings to resolve to `https:\u002F\u002F`.\n- `signal`: abort signal used by the initial connection request.\n- `timeoutMs`: timeout in milliseconds for the initial connection request.\n\nBecause this SDK only speaks Quack, the preferred form is a bare host string:\n`localhost:9494` or `localhost`. The default port is `9494`. DuckDB-style\n`quack:` URIs remain supported for compatibility with `quack_serve()` output and\nconfiguration.\n\nSupported connection string forms include:\n\n```ts\nawait QuackClient.connect(\"localhost:9494\", { authToken: \"super_secret\" });\nawait QuackClient.connect(\"localhost\", { authToken: \"super_secret\" });\nawait QuackClient.connect(\"quack:localhost:9494\", { authToken: \"super_secret\" });\nawait QuackClient.connect(\"quack:\u002F\u002Flocalhost:9494\", { authToken: \"super_secret\" });\nawait QuackClient.connect(\"http:\u002F\u002Flocalhost:9494\", { authToken: \"super_secret\" });\n```\n\nUse `withConnection()` when a connection should be scoped to one operation:\n\n```ts\nconst rows = await QuackClient.withConnection(\n  \"localhost:9494\",\n  { authToken: \"super_secret\" },\n  async (client) => {\n    return (await client.query(\"SELECT 1 AS value\")).rows();\n  }\n);\n```\n\nAfter connecting, server metadata is available as `client.info`:\n\n```ts\nconsole.log(client.info?.serverDuckdbVersion);\nconsole.log(client.info?.serverPlatform);\nconsole.log(client.info?.quackVersion);\n```\n\n## Query Results\n\n`query()` prepares the SQL, fetches all available result chunks, and returns a\nmaterialized result object:\n\n```ts\ntype ItemRow = { id: number; label: string };\n\nconst result = await client.query\u003CItemRow>(`\n  SELECT 1::INTEGER AS id, 'one'::VARCHAR AS label\n`);\n\nconsole.log(result.names); \u002F\u002F [\"id\", \"label\"]\nconsole.log(result.types); \u002F\u002F decoded DuckDB logical types\nconsole.log(result.chunks); \u002F\u002F decoded DuckDB DataChunks\nconsole.log(result.rows()); \u002F\u002F [{ id: 1, label: \"one\" }]\nconsole.log(result.jsonRows()); \u002F\u002F JSON-safe row objects\n```\n\nQueries accept positional or named parameters. Parameters are formatted as SQL\nliterals on the client side because the current Quack wire protocol does not\nprovide a separate bind-parameter message.\n\n```ts\nconst row = await client.one\u003CItemRow>(\n  \"SELECT ?::INTEGER AS id, ?::VARCHAR AS label\",\n  [1, \"one\"]\n);\n\nconst named = await client.first\u003CItemRow>(\n  \"SELECT :id::INTEGER AS id, :label::VARCHAR AS label\",\n  { id: 2, label: \"two\" }\n);\n```\n\nConvenience query methods:\n\n```ts\nawait client.first\u003CItemRow>(\"SELECT * FROM items ORDER BY id\"); \u002F\u002F ItemRow | null\nawait client.one\u003CItemRow>(\"SELECT * FROM items WHERE id = ?\", [1]); \u002F\u002F exactly one row\nawait client.values\u003Cbigint>(\"SELECT i FROM range(10) t(i)\"); \u002F\u002F first-column values\n```\n\nPass `signal` or `timeoutMs` to query, fetch, append, and disconnect calls:\n\n```ts\nawait client.query(\"SELECT * FROM slow_table\", { timeoutMs: 30_000 });\n```\n\nFor chunk-by-chunk processing, use `stream()`. For row-by-row processing, use\n`streamRows()`:\n\n```ts\nfor await (const chunk of client.stream(\"SELECT * FROM range(10000)\")) {\n  console.log(chunk.rowCount, chunk.columns.length);\n}\n\nfor await (const row of client.streamRows\u003C{ id: bigint }>(\"SELECT i AS id FROM range(10000) t(i)\")) {\n  console.log(row.id);\n}\n```\n\nTransactions use the existing connection and automatically roll back when the\ncallback throws:\n\n```ts\nawait client.transaction(async (tx) => {\n  await tx.query(\"INSERT INTO items VALUES (?, ?)\", [1, \"one\"]);\n  await tx.query(\"INSERT INTO items VALUES (?, ?)\", [2, \"two\"]);\n});\n```\n\n## Arrow Results\n\nThe SDK can expose query results as Apache Arrow data through\n`@uwdata\u002Fflechette`:\n\n```ts\nconst table = await client.queryArrow(\n  \"SELECT 1::INTEGER AS id, 12.34::DECIMAL(10, 2) AS amount\",\n  {\n    useDecimalInt: true,\n    useBigInt: true,\n    useBigIntTimestamp: true\n  }\n);\n\nconsole.log(table.numRows);\nconsole.log(table.toColumns());\nconsole.log(table.toArray());\n```\n\n`queryArrow()` accepts the same SQL parameter forms as `query()`, plus\nFlechette extraction options: `useDate`, `useDecimalInt`, `useBigInt`,\n`useBigIntTimestamp`, `useMap`, and `useProxy`.\n\nUse `queryArrowIPC()` to collect results as Arrow IPC bytes:\n\n```ts\nconst ipc = await client.queryArrowIPC(\"SELECT * FROM items\", {\n  format: \"stream\",\n  useBigInt: true\n});\n```\n\nFor chunk-by-chunk Arrow processing, use `streamArrow()`:\n\n```ts\nfor await (const table of client.streamArrow(\"SELECT * FROM range(10000)\")) {\n  console.log(table.numRows, table.names);\n}\n```\n\nLow-level conversion helpers are exported for callers that already have Quack\nchunks or Flechette tables:\n\n```ts\nimport {\n  arrowIPCFromChunks,\n  arrowTableFromChunks,\n  dataChunksFromArrowIPC,\n  dataChunksFromArrowTable\n} from \"@quack-protocol\u002Fsdk\";\n```\n\n## Appending Data\n\nFor application code, `appendRows()` is the most convenient append API:\n\n```ts\nimport {\n  LogicalTypes,\n  QuackClient\n} from \"@quack-protocol\u002Fsdk\";\n\nconst client = await QuackClient.connect(\"localhost:9494\", {\n  authToken: \"super_secret\"\n});\n\nawait client.query(`\n  CREATE TABLE target_table (\n    id INTEGER,\n    label VARCHAR,\n    amount DECIMAL(10, 2)\n  )\n`);\n\nawait client.appendRows(\n  \"target_table\",\n  [\n    { id: 1, label: \"a\", amount: \"12.34\" },\n    { id: 2, label: \"b\", amount: \"56.78\" },\n    { id: 3, label: \"c\", amount: null }\n  ],\n  {\n    columns: {\n      id: LogicalTypes.integer(),\n      label: LogicalTypes.varchar(),\n      amount: LogicalTypes.decimal(10, 2)\n    }\n  }\n);\n```\n\nUse a table reference object for schema-qualified appends:\n\n```ts\nawait client.appendRows(\n  { schema: \"analytics\", table: \"items\" },\n  rows,\n  { columns, batchSize: 1000 }\n);\n```\n\nFor low-level append workloads, build a DuckDB `DataChunk` directly:\n\n```ts\nimport { column, dataChunk, LogicalTypes } from \"@quack-protocol\u002Fsdk\";\n\nconst chunk = dataChunk([\n  column(LogicalTypes.integer(), [1, 2, 3], \"id\"),\n  column(LogicalTypes.varchar(), [\"a\", \"b\", \"c\"], \"label\")\n]);\n\nawait client.append(\"target_table\", chunk);\n```\n\n`append()` also accepts schema-qualified table references:\n\n```ts\nawait client.append({ schema: \"analytics\", table: \"items\" }, chunk);\n```\n\nArrow tables and Arrow IPC bytes can also be appended:\n\n```ts\nimport { decimal128, int32, tableFromArrays, utf8 } from \"@uwdata\u002Fflechette\";\nimport { LogicalTypes } from \"@quack-protocol\u002Fsdk\";\n\nconst arrow = tableFromArrays(\n  {\n    id: [1, 2],\n    label: [\"one\", \"two\"],\n    amount: [1234n, null]\n  },\n  {\n    types: {\n      id: int32(),\n      label: utf8(),\n      amount: decimal128(10, 2)\n    },\n    useDecimalInt: true\n  }\n);\n\nawait client.appendArrow(\"target_table\", arrow, {\n  duckTypes: {\n    id: LogicalTypes.integer(),\n    label: LogicalTypes.varchar(),\n    amount: LogicalTypes.decimal(10, 2)\n  },\n  useDecimalInt: true\n});\n```\n\nArrow data produced by this SDK includes DuckDB logical type metadata, so it can\nusually be appended back without `duckTypes`. External Arrow data should provide\n`duckTypes` when a DuckDB target type is ambiguous, for example decimals,\nenums, UUIDs, or temporal precision.\n\nThe builder keeps column names on the local chunk for row materialization, but\nQuack append uses the target table schema and column order.\n\n## Logical Types\n\nCommon helpers are available through `LogicalTypes`:\n\n```ts\nLogicalTypes.boolean();\nLogicalTypes.tinyint();\nLogicalTypes.smallint();\nLogicalTypes.integer();\nLogicalTypes.bigint();\nLogicalTypes.utinyint();\nLogicalTypes.usmallint();\nLogicalTypes.uinteger();\nLogicalTypes.ubigint();\nLogicalTypes.hugeint();\nLogicalTypes.uhugeint();\nLogicalTypes.float();\nLogicalTypes.double();\nLogicalTypes.char();\nLogicalTypes.varchar();\nLogicalTypes.blob();\nLogicalTypes.bit();\nLogicalTypes.uuid();\nLogicalTypes.date();\nLogicalTypes.time();\nLogicalTypes.timeNs();\nLogicalTypes.timeTz();\nLogicalTypes.timestamp();\nLogicalTypes.timestampSeconds();\nLogicalTypes.timestampMillis();\nLogicalTypes.timestampNanos();\nLogicalTypes.timestampTz();\nLogicalTypes.interval();\nLogicalTypes.decimal(18, 2);\nLogicalTypes.list(LogicalTypes.integer());\nLogicalTypes.map(LogicalTypes.varchar(), LogicalTypes.integer());\nLogicalTypes.struct([\n  { name: \"id\", type: LogicalTypes.integer() },\n  { name: \"label\", type: LogicalTypes.varchar() }\n]);\nLogicalTypes.array(LogicalTypes.integer(), 3);\nLogicalTypes.enum([\"sad\", \"ok\", \"happy\"]);\nLogicalTypes.geometry();\n```\n\nFor less common DuckDB logical types, use `logicalType()` and `LogicalTypeId`:\n\n```ts\nimport { logicalType, LogicalTypeId } from \"@quack-protocol\u002Fsdk\";\n\nconst timeType = logicalType(LogicalTypeId.TIME);\nconst timestampNsType = logicalType(LogicalTypeId.TIMESTAMP_NS);\n```\n\n## Value Representation\n\nDecoded rows use JavaScript primitives where they are lossless:\n\n- `BOOLEAN` becomes `boolean`.\n- Integer widths up to 32-bit become `number`.\n- 64-bit and 128-bit integers become `bigint`.\n- `FLOAT` and `DOUBLE` become `number`.\n- `VARCHAR`, `CHAR`, and `ENUM` become `string`.\n- `BLOB`, `BIT`, and `GEOMETRY` become `Uint8Array`.\n- `UUID` becomes a canonical UUID string.\n- `NULL` becomes `null`.\n\nDuckDB-specific values are represented as tagged objects:\n\n```ts\ntype DecimalValue = {\n  kind: \"decimal\";\n  value: bigint; \u002F\u002F unscaled integer\n  width: number;\n  scale: number;\n};\n\ntype DateValue = {\n  kind: \"date\";\n  days: number; \u002F\u002F days since 1970-01-01\n};\n\ntype TimeValue = {\n  kind: \"time\";\n  unit: \"micros\" | \"nanos\";\n  value: bigint;\n};\n\ntype TimeTzValue = {\n  kind: \"time_tz\";\n  bits: bigint; \u002F\u002F DuckDB packed TIME WITH TIME ZONE value\n};\n\ntype TimestampValue = {\n  kind: \"timestamp\";\n  unit: \"seconds\" | \"millis\" | \"micros\" | \"nanos\";\n  value: bigint;\n  timezone?: \"utc\";\n};\n\ntype IntervalValue = {\n  kind: \"interval\";\n  months: number;\n  days: number;\n  micros: bigint;\n};\n```\n\nBecause `rows()` can contain `bigint`, `Uint8Array`, and tagged values with\n`bigint` fields, its output is not guaranteed to be directly\n`JSON.stringify()`-safe. Use `jsonRows()` when you want JSON-safe row objects:\n\n```ts\nconst result = await client.query(`\n  SELECT\n    9007199254740993::BIGINT AS id,\n    12.34::DECIMAL(4, 2) AS amount,\n    'hi'::BLOB AS payload,\n    TIMESTAMP '1970-01-01 00:00:01.234567' AS ts\n`);\n\nconsole.log(result.jsonRows());\n\u002F\u002F [{\n\u002F\u002F   id: \"9007199254740993\",\n\u002F\u002F   amount: \"12.34\",\n\u002F\u002F   payload: \"aGk=\",\n\u002F\u002F   ts: \"1970-01-01T00:00:01.234567Z\"\n\u002F\u002F }]\n```\n\nDefault JSON conversions:\n\n- `bigint` becomes a string.\n- `Uint8Array` becomes a base64 string.\n- `DECIMAL` becomes a scaled decimal string.\n- `DATE` becomes an ISO `YYYY-MM-DD` string.\n- `TIME` becomes an `HH:MM:SS.fraction` string.\n- `TIMESTAMP` becomes an ISO timestamp string.\n- `TIME WITH TIME ZONE` remains tagged with its packed bits as a string.\n- `INTERVAL` remains tagged with `micros` as a string.\n- Lists and structs are converted recursively.\n\nYou can also convert individual values or rows:\n\n```ts\nimport {\n  dateFromISODate,\n  dateFromJSDate,\n  decimalToString,\n  decimalValue,\n  intervalValue,\n  toJsonRow,\n  toJsonRows,\n  toJsonValue,\n  timeTzValue,\n  timeValue,\n  timestampFromJSDate,\n  timestampValue\n} from \"@quack-protocol\u002Fsdk\";\n\nconsole.log(decimalToString(row.amount));\n\nconst amount = decimalValue(\"12.34\", 10, 2);\nconst day = dateFromISODate(\"2020-01-02\");\nconst timestamp = timestampFromJSDate(new Date(), \"micros\");\nconst interval = intervalValue(1, 2, 3n);\n\nconst jsonValue = toJsonValue(9007199254740993n);\nconst jsonRow = toJsonRow(row);\nconst jsonRows = toJsonRows(result.rows());\n```\n\nJSON conversion options let you choose a few alternate encodings:\n\n```ts\nresult.jsonRows({\n  bigint: \"string\", \u002F\u002F or \"number\" for safe integers only\n  bytes: \"base64\", \u002F\u002F or \"hex\" or \"array\"\n  decimal: \"string\", \u002F\u002F or \"tagged\"\n  date: \"iso\", \u002F\u002F or \"tagged\"\n  time: \"string\", \u002F\u002F or \"tagged\"\n  timestamp: \"iso\" \u002F\u002F or \"tagged\"\n});\n```\n\n## Package Exports\n\nThe root package exports the friendly client API, builders, logical types,\nvalue helpers, errors, and codec types. Low-level protocol and binary codec\nexports are also available through a dedicated subpath:\n\n```ts\nimport { QuackClient, LogicalTypes } from \"@quack-protocol\u002Fsdk\";\nimport { BinaryReader, decodeMessage } from \"@quack-protocol\u002Fsdk\u002Fprotocol\";\n```\n\n## Errors\n\nThe public error hierarchy is:\n\n- `QuackError`: base class.\n- `QuackProtocolError`: local transport, URI, codec, or client-state problem.\n- `QuackServerError`: Quack server returned an error response.\n- `QuackUnsupportedTypeError`: a known DuckDB serialization path is outside the\n  supported implementation surface.\n\n## Unsupported Metadata Paths\n\nThe supported protocol surface covers normal query results and append chunks.\nSome rare DuckDB-internal serialization paths are intentionally rejected with\n`QuackUnsupportedTypeError` because they require additional DuckDB internals\nrather than just the Quack envelope:\n\n- `FSST_VECTOR` compressed string vectors.\n- `ExtensionTypeInfo` metadata attached to logical types.\n- `UNBOUND_TYPE_INFO` when serialized with a `ParsedExpression` field.\n- `INTEGER_LITERAL_TYPE_INFO` when serialized with a DuckDB `Value` field.\n- Encoding integer literal metadata back to DuckDB.\n\nThese are explicit failures, not silent lossy decodes. Standard SQL result\ntypes, nested result vectors, and flat append chunks do not normally require\nthese paths.\n\n## Local Quack Server\n\nThe repository includes a helper script that starts DuckDB, installs and loads\nthe Quack extension, and calls `quack_serve()`:\n\n```sh\nnpm run serve:quack\n```\n\nDefaults:\n\n- `QUACK_SERVER_URI=quack:localhost`\n- `QUACK_AUTH_TOKEN=super_secret`\n- `QUACK_EXTENSION_REPOSITORY=core_nightly`\n- `DUCKDB_BIN=duckdb`\n\nOverride them as needed:\n\n```sh\nQUACK_SERVER_URI=quack:localhost:9494 \\\nQUACK_AUTH_TOKEN=my_secret \\\nDUCKDB_BIN=\u002Fpath\u002Fto\u002Fduckdb \\\nnpm run serve:quack\n```\n\nThe script also accepts the URI as its first argument:\n\n```sh\nbash scripts\u002Fstart-quack-server.sh quack:localhost:9494\n```\n\nAdditional server environment variables:\n\n- `DUCKDB_DATABASE`: optional database path passed to the DuckDB CLI.\n- `QUACK_EXTENSION_REPOSITORY`: extension repository name. Set it to an empty\n  value to run `INSTALL quack;` without an explicit repository.\n\n## Scripts\n\n- `npm run build`: type-checks with TypeScript and bundles the ESM library with\n  Vite.\n- `npm run test`: runs unit tests for URI parsing, binary codecs, message\n  codecs, logical type handling, and chunk encoding\u002Fdecoding.\n- `npm run test:watch`: runs Vitest in watch mode.\n- `npm run check:duckdb`: verifies the local DuckDB CLI is at least `1.5.2`.\n- `npm run serve:quack`: starts a local DuckDB Quack server.\n- `npm run test:integration`: runs the live integration suite through\n  `vitest.integration.config.ts`.\n\n## Integration Tests\n\nThe integration tests run against a real DuckDB Quack server. If\n`QUACK_INTEGRATION_URL` is set, the suite uses that server:\n\n```sh\nQUACK_INTEGRATION_URL=localhost:9494 \\\nQUACK_AUTH_TOKEN=super_secret \\\nnpm run test:integration\n```\n\nIf `QUACK_INTEGRATION_URL` is not set, Vitest global setup starts a temporary\nlocal server with `scripts\u002Fstart-quack-server.sh`, waits for it to become ready,\nand tears it down after the suite.\n\nIntegration environment variables:\n\n- `QUACK_INTEGRATION_URL`: use an already-running server instead of starting\n  one.\n- `QUACK_AUTH_TOKEN`: token used by the integration client. Defaults to\n  `super_secret` when using an external server, and to a generated token when\n  global setup starts the server.\n- `QUACK_START_LOCAL_SERVER=0`: disable automatic local server startup.\n- `QUACK_SERVER_URI`: URI used by the startup script when global setup starts a\n  server.\n- `QUACK_SERVER_START_TIMEOUT_MS`: readiness timeout, defaulting to `30000`.\n\nCurrent integration coverage includes authentication, URI handling, connection\nlifecycle, connection metadata, query result metadata, parameterized query\nhelpers, empty result sets, fetch pagination, chunk and row streaming, large\nresults, transactions, scalar result decoding, nested result decoding, scalar\nappend, nested append, row-oriented append, schema-qualified append, zero-row\nappend chunks, concurrency, and server error responses.\n\nCI and release workflows install DuckDB CLI `v1.5.2` from\n`https:\u002F\u002Finstall.duckdb.org\u002Fv1.5.2\u002Fduckdb_cli-linux-amd64.zip` and run the live\nintegration suite before a release is published.\n","这是一个TypeScript客户端库，用于支持DuckDB的实验性Quack协议。项目实现了Quack HTTP传输、二进制序列化编码与解码、逻辑类型元数据处理以及数据块的编解码功能，特别适用于数据追加场景。该库采用ESM模块标准，无运行时依赖，并利用了标准fetch API，确保了在现代浏览器、Node.js及其他兼容fetch实现的环境中良好运行。适合需要直接与DuckDB数据库进行高效交互的应用程序开发场景，尤其是那些涉及大量数据导入或查询执行的任务。",2,"2026-06-11 04:05:37","CREATED_QUERY"]