@zvndev/powdb-client 0.11.0 → 0.12.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
@@ -298,21 +298,31 @@ import { Client } from "@zvndev/powdb-client";
298
298
  const client = await Client.connect({ host: "localhost", port: 5433 });
299
299
 
300
300
  const rows = await client.queryTyped(
301
- "User { .id, .name, .age, .active, .created_at }",
301
+ "User { .id, .name, .age, .active, .created_at, .prefs }",
302
302
  {
303
303
  id: "int", // number — or bigint if > Number.MAX_SAFE_INTEGER
304
304
  age: "int",
305
305
  active: "bool",
306
306
  created_at: "datetime",
307
+ prefs: "json", // parsed with JSON.parse into an object/array/scalar
307
308
  // columns not in the schema (like `name`) pass through as strings
308
309
  },
309
310
  );
310
311
 
311
312
  rows[0].age; // typeof number
312
313
  rows[0].created_at; // instanceof Date
314
+ rows[0].prefs; // parsed JSON value (object, array, or scalar)
313
315
  ```
314
316
 
315
- Supported column types: `int` | `float` | `bool` | `str` | `datetime` | `uuid`.
317
+ Supported column types: `int` | `float` | `bool` | `str` | `datetime` | `uuid` | `json`.
318
+
319
+ `json` columns render as canonical JSON text on the wire (keys sorted
320
+ bytewise, no whitespace) and are parsed with `JSON.parse`. A JSON `null`
321
+ document decodes to `null`. Unlike the other typed columns, a parse failure
322
+ does not throw: it returns the raw string, so a malformed or non-canonical
323
+ cell can never turn a readable result into an exception (canonical server
324
+ output always parses, so this fallback is inert in normal use).
325
+
316
326
  Bytes columns are intentionally unsupported (the wire format is lossy —
317
327
  it renders `<N bytes>`) and throw on coercion. Declare `str` if you just
318
328
  want the placeholder.
@@ -19,7 +19,7 @@ import { EventEmitter } from "node:events";
19
19
  import { type SyncRepairAction, type WireRetainedUnit, type WireSyncStatus } from "./protocol.js";
20
20
  import { type TypedRow, type TypedSchema } from "./typed.js";
21
21
  /** Client library version. Compared to the server's reported version. */
22
- export declare const CLIENT_VERSION = "0.11.0";
22
+ export declare const CLIENT_VERSION = "0.12.0";
23
23
  export type QueryResult = {
24
24
  kind: "rows";
25
25
  columns: string[];
@@ -390,4 +390,4 @@ export { splitStatements } from "./script.js";
390
390
  export { PowDBError, isPowDBError, PowDBScriptError, isPowDBScriptError, } from "./errors.js";
391
391
  export type { PowDBErrorCode } from "./errors.js";
392
392
  export { coerceValue, coerceRow, coerceRows, } from "./typed.js";
393
- export type { ColumnType, TypedSchema, TypedRow, Coerced, } from "./typed.js";
393
+ export type { ColumnType, TypedSchema, TypedRow, Coerced, JsonValue, } from "./typed.js";
package/dist/cjs/index.js CHANGED
@@ -58,7 +58,7 @@ const errors_js_1 = require("./errors.js");
58
58
  const script_js_1 = require("./script.js");
59
59
  const typed_js_1 = require("./typed.js");
60
60
  /** Client library version. Compared to the server's reported version. */
61
- exports.CLIENT_VERSION = "0.11.0";
61
+ exports.CLIENT_VERSION = "0.12.0";
62
62
  /** Transaction-control statements a `transactional` script may not contain. */
63
63
  const TX_CONTROL_RE = /^(begin|commit|rollback)\b/i;
64
64
  /**
@@ -9,6 +9,7 @@
9
9
  * Str → raw UTF-8 (may contain anything)
10
10
  * DateTime → microseconds since Unix epoch as decimal, e.g. "1718928000000000"
11
11
  * Uuid → canonical "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
12
+ * Json → canonical JSON text (keys sorted bytewise, no whitespace)
12
13
  * Bytes → "<N bytes>" (LOSSY — see note below)
13
14
  *
14
15
  * `queryTyped` takes a user-supplied schema and coerces each column string
@@ -24,14 +25,18 @@
24
25
  * schema if you just want the `<N bytes>` placeholder.
25
26
  */
26
27
  /**
27
- * Supported column types. Mirrors the server's `DataType` enum minus the
28
+ * Supported column types. Mirrors the server's `TypeId` enum minus the
28
29
  * `Bytes` variant, which is intentionally unsupported here.
29
30
  */
30
- export type ColumnType = "int" | "float" | "bool" | "str" | "datetime" | "uuid";
31
+ export type ColumnType = "int" | "float" | "bool" | "str" | "datetime" | "uuid" | "json";
31
32
  /** Map of column name → declared type. Columns not in the map pass through as strings. */
32
33
  export type TypedSchema = Record<string, ColumnType>;
34
+ /** Any value produced by `JSON.parse` of a canonical JSON document. */
35
+ export type JsonValue = null | boolean | number | string | JsonValue[] | {
36
+ [key: string]: JsonValue;
37
+ };
33
38
  /** Coerced value type. `int` may return `bigint` if the value exceeds Number.MAX_SAFE_INTEGER. */
34
- export type Coerced = number | bigint | boolean | string | Date | null;
39
+ export type Coerced = number | bigint | boolean | string | Date | null | JsonValue;
35
40
  /** A row of coerced values keyed by column name. */
36
41
  export type TypedRow = Record<string, Coerced>;
37
42
  /**
package/dist/cjs/typed.js CHANGED
@@ -10,6 +10,7 @@
10
10
  * Str → raw UTF-8 (may contain anything)
11
11
  * DateTime → microseconds since Unix epoch as decimal, e.g. "1718928000000000"
12
12
  * Uuid → canonical "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
13
+ * Json → canonical JSON text (keys sorted bytewise, no whitespace)
13
14
  * Bytes → "<N bytes>" (LOSSY — see note below)
14
15
  *
15
16
  * `queryTyped` takes a user-supplied schema and coerces each column string
@@ -85,6 +86,25 @@ function coerceValue(column, raw, type) {
85
86
  }
86
87
  return raw;
87
88
  }
89
+ case "json": {
90
+ // The server renders json cells as canonical JSON text, so JSON.parse
91
+ // reconstructs the document (object, array, or scalar). A JSON `null`
92
+ // document already returned above via the shared null-sentinel guard.
93
+ //
94
+ // Unlike the other typed columns, a parse failure does NOT throw: it
95
+ // returns the raw string. Rationale: json is the one column type whose
96
+ // wire text is not a fixed, server-controlled shape a client can fully
97
+ // predict, and a future server that ever emits a non-canonical cell (or
98
+ // a proxy that rewrites it) must not turn a readable result into an
99
+ // exception. Canonical output always parses, so this fallback is inert
100
+ // in normal operation and exists purely as a safety net.
101
+ try {
102
+ return JSON.parse(raw);
103
+ }
104
+ catch {
105
+ return raw;
106
+ }
107
+ }
88
108
  }
89
109
  }
90
110
  /**
package/dist/index.d.ts CHANGED
@@ -19,7 +19,7 @@ import { EventEmitter } from "node:events";
19
19
  import { type SyncRepairAction, type WireRetainedUnit, type WireSyncStatus } from "./protocol.js";
20
20
  import { type TypedRow, type TypedSchema } from "./typed.js";
21
21
  /** Client library version. Compared to the server's reported version. */
22
- export declare const CLIENT_VERSION = "0.11.0";
22
+ export declare const CLIENT_VERSION = "0.12.0";
23
23
  export type QueryResult = {
24
24
  kind: "rows";
25
25
  columns: string[];
@@ -390,4 +390,4 @@ export { splitStatements } from "./script.js";
390
390
  export { PowDBError, isPowDBError, PowDBScriptError, isPowDBScriptError, } from "./errors.js";
391
391
  export type { PowDBErrorCode } from "./errors.js";
392
392
  export { coerceValue, coerceRow, coerceRows, } from "./typed.js";
393
- export type { ColumnType, TypedSchema, TypedRow, Coerced, } from "./typed.js";
393
+ export type { ColumnType, TypedSchema, TypedRow, Coerced, JsonValue, } from "./typed.js";
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ import { PowDBError, PowDBScriptError, isPowDBError } from "./errors.js";
22
22
  import { splitStatements } from "./script.js";
23
23
  import { coerceRows, } from "./typed.js";
24
24
  /** Client library version. Compared to the server's reported version. */
25
- export const CLIENT_VERSION = "0.11.0";
25
+ export const CLIENT_VERSION = "0.12.0";
26
26
  /** Transaction-control statements a `transactional` script may not contain. */
27
27
  const TX_CONTROL_RE = /^(begin|commit|rollback)\b/i;
28
28
  /**
package/dist/typed.d.ts CHANGED
@@ -9,6 +9,7 @@
9
9
  * Str → raw UTF-8 (may contain anything)
10
10
  * DateTime → microseconds since Unix epoch as decimal, e.g. "1718928000000000"
11
11
  * Uuid → canonical "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
12
+ * Json → canonical JSON text (keys sorted bytewise, no whitespace)
12
13
  * Bytes → "<N bytes>" (LOSSY — see note below)
13
14
  *
14
15
  * `queryTyped` takes a user-supplied schema and coerces each column string
@@ -24,14 +25,18 @@
24
25
  * schema if you just want the `<N bytes>` placeholder.
25
26
  */
26
27
  /**
27
- * Supported column types. Mirrors the server's `DataType` enum minus the
28
+ * Supported column types. Mirrors the server's `TypeId` enum minus the
28
29
  * `Bytes` variant, which is intentionally unsupported here.
29
30
  */
30
- export type ColumnType = "int" | "float" | "bool" | "str" | "datetime" | "uuid";
31
+ export type ColumnType = "int" | "float" | "bool" | "str" | "datetime" | "uuid" | "json";
31
32
  /** Map of column name → declared type. Columns not in the map pass through as strings. */
32
33
  export type TypedSchema = Record<string, ColumnType>;
34
+ /** Any value produced by `JSON.parse` of a canonical JSON document. */
35
+ export type JsonValue = null | boolean | number | string | JsonValue[] | {
36
+ [key: string]: JsonValue;
37
+ };
33
38
  /** Coerced value type. `int` may return `bigint` if the value exceeds Number.MAX_SAFE_INTEGER. */
34
- export type Coerced = number | bigint | boolean | string | Date | null;
39
+ export type Coerced = number | bigint | boolean | string | Date | null | JsonValue;
35
40
  /** A row of coerced values keyed by column name. */
36
41
  export type TypedRow = Record<string, Coerced>;
37
42
  /**
package/dist/typed.js CHANGED
@@ -9,6 +9,7 @@
9
9
  * Str → raw UTF-8 (may contain anything)
10
10
  * DateTime → microseconds since Unix epoch as decimal, e.g. "1718928000000000"
11
11
  * Uuid → canonical "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
12
+ * Json → canonical JSON text (keys sorted bytewise, no whitespace)
12
13
  * Bytes → "<N bytes>" (LOSSY — see note below)
13
14
  *
14
15
  * `queryTyped` takes a user-supplied schema and coerces each column string
@@ -80,6 +81,25 @@ export function coerceValue(column, raw, type) {
80
81
  }
81
82
  return raw;
82
83
  }
84
+ case "json": {
85
+ // The server renders json cells as canonical JSON text, so JSON.parse
86
+ // reconstructs the document (object, array, or scalar). A JSON `null`
87
+ // document already returned above via the shared null-sentinel guard.
88
+ //
89
+ // Unlike the other typed columns, a parse failure does NOT throw: it
90
+ // returns the raw string. Rationale: json is the one column type whose
91
+ // wire text is not a fixed, server-controlled shape a client can fully
92
+ // predict, and a future server that ever emits a non-canonical cell (or
93
+ // a proxy that rewrites it) must not turn a readable result into an
94
+ // exception. Canonical output always parses, so this fallback is inert
95
+ // in normal operation and exists purely as a safety net.
96
+ try {
97
+ return JSON.parse(raw);
98
+ }
99
+ catch {
100
+ return raw;
101
+ }
102
+ }
83
103
  }
84
104
  }
85
105
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zvndev/powdb-client",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "TypeScript client for PowDB (PowQL wire protocol)",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.29.3",